简体   繁体   中英

Java JApplet render issues

I have a problem with JApplet. The code was working just fine, but when I converted it from JFrame to JApplet, the render part stopped working properly. Basicly what I'm trying to do is simplistic draw app. When launching applet, half of time repaint() is not working (There is no gray background; you have to put mouse over button for it to update its color etc), furtheremore the pixel rendering part is not shown up at all. Here's the code:

The Frame class (JApplet)

  package painter;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Frame extends JApplet {

public JPanel panel;
private JButton plus, minus, buttonColor;
private int scaleSize;
private JLabel labelScale;
private final Timer updateTimer;
private static boolean painting = false;
public static Color currentColor;
public static int mode = 0;
// 0 = draw; 1 = setcolor; 2 = erase

private ArrayList<Pixel> pixelArray;

public Frame() {

    pixelArray = new ArrayList<>();
    for (int i = 1; i <= 8; i++) {
        for (int j = 1; j <= 8; j++) {
            pixelArray.add(new Pixel(i, j));
        }
    }

    setLayout(new BorderLayout());
    panel = new JPanel() {

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            //g.fillRect(10, 10, 100, 100);  <- test if fillRect works at all. Yus it does.
            for (int i = 0; i < pixelArray.size(); i++) {
                pixelArray.get(i).render(g);
            }
            Toolkit.getDefaultToolkit().sync();
            g.dispose();
        }

    };

    //panel.setBounds(0, 0, 800, 800);
    //add(panel);
    getContentPane().add(panel);
    //panel.setLayout(null);
    //panel.setOpaque(true);

    //panel.setDoubleBuffered(true);
    currentColor = Color.yellow;

    buttonColor = new JButton("Choose color");
    buttonColor.setBounds(10, 10, 128, 64);
    buttonColor.setBackground(currentColor);
    buttonColor.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            currentColor = JColorChooser.showDialog(null, "JColorChooser Sample", Color.gray);
        }

    });

    updateTimer = new Timer(20, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            buttonColor.setBackground(currentColor);
            repaint();
        }

    });
    updateTimer.start();
    addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            painting = true;
        }
    });
    addMouseListener(new MouseAdapter() {
        @Override
        public void mouseReleased(MouseEvent e) {
            painting = false;
        }
    });

    panel.add(buttonColor);

    repaint();
}

public static boolean getPaint() {
    return painting;
}

public static void main(String[] args) {
    new Frame();
}
}

And here is the Pixel class:

package painter;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.Point;

public class Pixel {

private Color color;
private int size;
private int x, y, relativex, relativey;

public Pixel(int relx, int rely) {
    color = new Color(0x999999, false);
    size = 32;
    x = relx * size + 64;
    y = rely * size + 64;

}

public boolean mouseOver() {
    Point pos, mousepos;
    pos = new Point(x, y);
    mousepos = MouseInfo.getPointerInfo().getLocation();
    if ((mousepos.x > pos.x)
            && (mousepos.x < pos.x + size)
            && (mousepos.y > pos.y)
            && (mousepos.y < pos.y + size)) {
        return true;
    } else {
        return false;
    }
}

public void render(Graphics g) {
    g.setColor(color);
    if (mouseOver() && Frame.getPaint()) {

        if (Frame.mode == 0) {
            color = Frame.currentColor;
        }
        if (Frame.mode == 1) {
            Frame.currentColor = color;
        }
        if (Frame.mode == 2) {
            color = new Color(0xffffffff, true);
        }
    }

    g.fillRect(x, y, size, size);
    if (mouseOver()) {
        g.setColor(Color.black);
        g.drawRect(x, y, size - 1, size - 1);
        g.setColor(Color.yellow);
        g.drawRect(x + 1, y + 1, size - 3, size - 3);
    }
    //g.fillRect(10, 10, 250, 250);
}

}

As a stab in the dark, don't call Graphics#dipose on a Graphics context you did not create yourself explicitly

Apart from the fact the the Graphics context is a shared resource, used by all the components that might need to be painted within a given paint cycle, it can also prevent what ever was painted to it to be displayed on some platforms

In 15 years of professional development, I've never had reason to call Toolkit.getDefaultToolkit().sync(); . I doubt it'll make that big a difference, I'm just saying

Java applets provide us with these methods

[here] http://docs.oracle.com/javase/tutorial/deployment/applet/appletMethods.html

the method

public void paint(Graphics g){}

is used as alternative of

public void paintComponent(Graphics g){}

of swing.

请查看http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html ,以获取推荐的方式来执行自定义绘制摆动组件的方法

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM