【问题标题】:Java JApplet render issuesJava JApplet 渲染问题
【发布时间】:2014-05-24 08:47:15
【问题描述】:

我对 JApplet 有疑问。代码工作得很好,但是当我将它从 JFrame 转换为 JApplet 时,渲染部分停止正常工作。基本上我想做的是简单的绘图应用程序。启动小程序时,有一半时间 repaint() 不起作用(没有灰色背景;您必须将鼠标悬停在按钮上才能更新其颜色等),而且根本不显示像素渲染部分。代码如下:

Frame 类 (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();
}
}

这是 Pixel 类:

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);
}

}

【问题讨论】:

  • "..但是当我将它从 JFrame 转换为 JApplet" 为什么你将它从框架转换为小程序而不是启动(工作) 来自使用Java Web Start的链接的框架?
  • "..furtheremore the.." 哇哦。 SO 不是“一站式服务台”,而是一个问答网站。说到这里,您的具体问题是什么?为了尽快获得更好的帮助,请发布MCVE(最小完整且可验证的示例)。
  • @AndrewThompson 这个项目从一开始就应该是一个小程序,但我首先将它作为 JFrame,因为它更容易测试并且错误更少。此外,我只是想提供渲染不起作用的证据,我唯一的问题是为什么。
  • 不要调用你的自定义类Frame。有一个同名的 AWT 组件,因此令人困惑。使用更具描述性的名称。

标签: java swing paintcomponent japplet


【解决方案1】:

作为暗中的刺,不要在您没有明确创建自己的 Graphics 上下文中调用 Graphics#dipose

除了Graphics 上下文是一个共享资源,所有可能需要在给定绘制周期内绘制的组件都使用它之外,它还可以防止曾经绘制到它的内容显示在某些平台

在 15 年的专业发展中,我从来没有理由致电 Toolkit.getDefaultToolkit().sync();。我怀疑它会产生那么大的不同,我只是说

【讨论】:

  • 我找到了解决方案:MouseInfo.getPointerInfo().getLocation() 只是出于某种原因搞砸了一切。不过我觉得你的建议很有帮助,所以我会给你最好的答案。
  • 不要使用MouseInfo,使用MouseListenerMouseMotionListener
【解决方案2】:

Java 小程序为我们提供了这些方法

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

方法

public void paint(Graphics g){}

用作

的替代品
public void paintComponent(Graphics g){}

摇摆。

【讨论】:

  • 没有t mention, but I tried everything: paint, paintComponent, hell even paint method inside JApplet. Doesnt 解决了问题。
  • 其实你有那种落后。顶级容器,如 JApplet,只有一个 paint 方法,这是故意的,因为大多数 Swing 顶级容器还包含其他组件,JRootPane,内容通道,可能还有一个玻璃窗格,所以提供一个 paintComponnent 方法没有什么意义,因为它会被其他东西覆盖。从 JComponent 扩展而来的组件除了其他绘画方法外,还有paintCompnent,它提供了一种可以轻松自定义绘画的方法
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2011-11-12
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 2023-01-02
    • 2016-04-01
    • 2010-10-19
    • 2016-06-27
    • 2010-11-29
    相关资源
    最近更新 更多