且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java的BufferedImage的工作在appletviewer中而不是浏览器

更新时间:2022-12-12 16:00:24

您是从当前文件夹中加载图像。这将使用,如果你从那里你有你的照片你的bin文件夹运行它的appletviewer时工作,但不是实际的小程序,因为它不知道的路径bin文件夹。

办法修正将是两种:


  • 使用文件系统API来对硬盘,这将需要正确的访问某个特定位置的权限/ privieges,

  • 包包含您的小程序(这里只引用一个类,它似乎相当奇怪),并访问它们的资源JAR中的图像,

  • 或正常服务从网络服务器(即使是本地测试)的小程序和查询的图像的服务器远程为好。

I'm new Java and I have an applet project to do for school which is all done. It works fine when I run it through the the appletviewer command line but when I preview it through the browser, the images do not show.

To make this short, my application must display a map of Canada and have a button for each of the provinces. Whenever a province is clicked, it must show that the province is selected in the map, show the province name and capital's name. I draw the map image in a JPanel. Like I said it works fine when I preview the applet through the appletviewer command line but when I load it through a browser, the images are not displayed.

The applet plays a background music which works fine and a clicking sound when the mouse is pressed and that also works. I'm really confused as to why the images are not showing.

Any help would be greatly appreciated. Thanks in advance.

Here is the code for the main class: package appletCanada;

import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class AppletCanada extends JApplet implements Runnable, ActionListener {
private BufferedImage[] img_map;
private BufferedImage[] img_flags;
private JPanel panelMap;

public void init() {

            //Initializing the buffered image array to be used for the map
            File[] file_images = new File[11];
    img_map = new BufferedImage[11];
    String[] str_img = new String[11];

    try {

        for(int i = 0; i < img_map.length; i++) {
            str_img[i] = this.getParameter("image" + i);
            file_images[i] = new File(str_img[i]);
            img_map[i] = ImageIO.read(file_images[i]);
        }

    }
    catch(Exception e) {}

    //Initializing the buffered images to be used as flags
    img_flags = new BufferedImage[10];
    try {
        for(int i = 0; i < img_flags.length; i++) {
            str_img[i] = this.getParameter("flag" + i);
            file_images[i] = new File(str_img[i]);
            img_flags[i] = ImageIO.read(file_images[i]);
        }
    }catch(Exception e) {}

            //Initializing the container
    iWindow = getContentPane();

    //Initializing the JPanels
    panelMap = new PanelMap(img_map, img_flags, str_prov, str_caps);

//Initializing the panel's layouts
    iWindow.setLayout(new GridBagLayout());

    //Initializing the GridBagConstraints object
    c = new GridBagConstraints();

defineC(0, 3, GridBagConstraints.CENTER, 5, 10, 15, 10, 15);
    iWindow.add(panelMap, c);

}

public void actionPerformed(ActionEvent e) {

    //When the button is clicked, the click sound is played and all button font goes to blue
    if(e != null) {
        click.play();
        btn_prov_01.setForeground(light_blue);
        btn_prov_02.setForeground(light_blue);              
        btn_prov_03.setForeground(light_blue);              
        btn_prov_04.setForeground(light_blue);              
        btn_prov_05.setForeground(light_blue);
        btn_prov_06.setForeground(light_blue);              
        btn_prov_07.setForeground(light_blue);
        btn_prov_08.setForeground(light_blue);              
        btn_prov_09.setForeground(light_blue);              
        btn_prov_10.setForeground(light_blue);
    }

//The province integer is assigned a value depending on the button that is clicked
    if(e.getSource() == btn_prov_00) {
        province = 0;
        panelMap.repaint();
    }
    else if(e.getSource() == btn_prov_01) {
        province = 1;
        panelMap.repaint();
        clickThread = new AnimButton(btn_prov_01);
        clickThread.start();
    }
    else if(e.getSource() == btn_prov_02) {
        province = 2;
        panelMap.repaint();
        clickThread = new AnimButton(btn_prov_02);
        clickThread.start();
    }
    //Goes on with the rest of the buttons
}

And here is the code for the PanelMap class: package appletCanada;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

public class PanelMap extends JPanel {

//Defining objects
private Image[] img_map;
private Image[] img_flags;
private String[] str_prov;
private String[] str_caps;
private Color light_blue = new Color(70, 158, 255);

//Class constructor
public PanelMap(BufferedImage[] image, BufferedImage[] img_flags, String[] str_prov, String[] str_caps) {
    this.setBorder(BorderFactory.createLineBorder(light_blue, 2));
    this.setPreferredSize(new Dimension(680, 580));
    this.setMaximumSize(new Dimension(680, 580));
    this.setMinimumSize(new Dimension(680, 580));
    this.setVisible(true);
    this.img_map = image;
    this.img_flags = img_flags;
    this.str_prov = str_prov;
    this.str_caps = str_caps;


}

//Method that paints the right map and province info depending on the province integer value from the AppletCanada class
public void paintComponent(Graphics g) {

    super.paintComponent(g);

    Font font_prov = new Font("arial", Font.BOLD, 16);
    Font font_cap  = new Font("arial", Font.PLAIN, 12);
    Color orange   = new Color(255, 128, 0);

    //If no province is selected
    if(AppletCanada.province == 0) {
        g.drawImage(img_map[0], 0, 0, this);
        g.setColor(orange);
        g.fillOval(470, 500, 10, 10);
        g.fillRect(428, 408, 154, 54);

        g.setColor(Color.white);
        g.fillRect(430, 410, 150, 40);

        g.setColor(orange);
        g.drawLine(475, 505, 505, 460);
        g.setFont(font_prov);

        g.setColor(light_blue);
        g.drawString("Capitale Nationale", 435, 425);
        g.setFont(font_cap);

        g.setColor(Color.black);
        g.drawString("Ottawa", 435, 440);
    }
    //If BC is selected
    else if(AppletCanada.province == 1) {
        g.drawImage(img_map[1], 0, 0, this);
        g.setColor(orange);
        g.fillOval(50, 430, 10, 10);
        g.fillRect(20, 350, 184, 50);

        g.setColor(Color.white);
        g.fillRect(22, 352, 180, 40);

        g.setColor(light_blue);
        g.setFont(font_prov);
        g.drawString(str_prov[0], 27, 367);

        g.setColor(Color.black);
        g.setFont(font_cap);
        g.drawString(str_caps[0], 27, 382);
        g.drawImage(img_flags[0], 170, 373, this);

        g.setColor(orange);
        g.drawLine(55, 435, 70, 400);
    }
//Goes one and does the same for the rest of the provinces

Here is the html code:

<head> 
<title>Map du Canada</title> 
</head> 

<body> 

<applet code="appletCanada.AppletCanada.class" width=800 height=800> 
<param name="image0" value="image0.png">
<param name="image1" value="image1.png">
<param name="image2" value="image2.png">
<param name="image3" value="image3.png">
<param name="image4" value="image4.png">
<param name="image5" value="image5.png">
<param name="image6" value="image6.png">
<param name="image7" value="image7.png">
<param name="image8" value="image8.png">
<param name="image9" value="image9.png">
<param name="image10" value="image10.png">
<param name="flag0" value="flag_01.gif">
<param name="flag1" value="flag_02.gif">
<param name="flag2" value="flag_03.gif">
<param name="flag3" value="flag_04.gif">
<param name="flag4" value="flag_05.gif">
<param name="flag5" value="flag_06.gif">
<param name="flag6" value="flag_07.gif">
<param name="flag7" value="flag_08.gif">
<param name="flag8" value="flag_09.gif">
<param name="flag9" value="flag_10.gif">
<param name="audio" value="canadian_anthem.wav">
<param name="click" value="click.aif">
</applet> 

</body> 

</html> 

You are loading images from the current folder. This will work when using the appletviewer if you run it from your "bin" folder where you have your images, but not in an actual Applet as it won't know the path to that "bin" folder.

Correct approaches would be to either:

  • use the filesystem APIs to access a specific location on the harddrive, which is going to require the right permissions/privieges,
  • package the images within a JAR containing your applet (here you only reference a single class, which seems rather odd) and access them as resources,
  • or properly serve the applet from a web server (even for local testing) and query the server for the images remotely as well.