我正在使用Java中的简单绘图板,我有一些用户可以使用的工具:笔和橡皮擦。但是用于选择工具的JComboBox没有出现,即使它被添加了。我听说定制油漆会掩盖任何JComponents。如果这是真的,我怎样才能让JComboBox始终处于领先地位?
窗口图片:
这是我的代码:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JFrame;
public class DrawFrame extends JFrame implements MouseMotionListener, Runnable {
private static final long serialVersionUID = 1L;
private Image dbi;
private Graphics dbg;
ArrayList<Integer> px = new ArrayList<Integer>();
ArrayList<Integer> py = new ArrayList<Integer>();
int mx;
int my;
@SuppressWarnings("rawtypes")
JComboBox tool = new JComboBox();
@SuppressWarnings("unchecked")
public DrawFrame() {
setSize(480, 480);
setTitle("ScratchPad _14");
setLayout(new FlowLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setBackground(Color.WHITE);
setOpacity(1);
tool.addItem("Pen");
tool.addItem("Eraser");
tool.setEnabled(true);
add(tool);
setVisible(true);
addMouseMotionListener(this);
}
/*@Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}*/
public static void main(String[] args) {
// TODO Auto-generated method stub
DrawFrame df = new DrawFrame();
Thread t = new Thread(df);
t.start();
}
public void paint(Graphics g) {
dbi = createImage(getWidth(), getHeight());
dbg = dbi.getGraphics();
draw(dbg);
g.drawImage(dbi, 0, 0, null);
}
private void draw(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
for (int i = 0; i < px.size(); i++) {
g.fillOval(px.get(i), py.get(i), 3, 3);
}
g.setColor(Color.BLUE);
g.drawString("(" + mx + ", " + my + ")", mx + 10, my - 5);
repaint();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void mouseDragged(MouseEvent m) {
// TODO Auto-generated method stub
int x = m.getX();
int y = m.getY();
mx = x;
my = y;
px.add(x);
py.add(y);
}
@Override
public void mouseMoved(MouseEvent m) {
// TODO Auto-generated method stub
int x = m.getX();
int y = m.getY();
mx = x;
my = y;
}
}
提前致谢!
答案 0 :(得分:2)
因为您调用了super.paint
,其中绘制了子组件,以及其他内容
super.paint(g);
然后使用...
用背景颜色填充整个帧g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
在它之前绘制的擦除......
你应该避免覆盖paint
等顶级容器JFrame
,除了你在框架装饰下绘画并且它不是双重缓冲的事实,这些容器实际上是由一个编号产生最终输出的复合成分。
而是创建一个自定义组件,例如JPanel
,并覆盖其paintComponent
方法。将您的自定义绘画放在这里。
将组合框和自定义绘画面板分别添加到框架
此外,不要从任何可能生成重绘事件的绘制方法中调用任何内容(如调用repaint
),这将设置一个无限循环,这将很快消耗你的CPU
请查看Performing Custom Painting了解详情
答案 1 :(得分:0)
通常,通常应该不覆盖JFrame的paint方法。相反,您应该扩展JPanel,并使用重写的paintComponent
方法进行绘制。
class PaintPanel extends JPanel
{
public PaintPanel()
{
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g)
{
// Paint what you have been painting
// in your "draw" method ...
...
super.paintComponent(g);
}
}
通常,super.paintComponent(g)
调用应该是对这种重写方法的第一次调用,但由于你想要将ComboBox绘制在你自己绘制的所有内容之上,它必须是最后一个。
其他问题:
稍微清理一下,而不是“很好”,但是......仍然像原始程序一样,至少:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DrawFrame extends JFrame implements MouseMotionListener {
private static final long serialVersionUID = 1L;
ArrayList<Integer> px = new ArrayList<Integer>();
ArrayList<Integer> py = new ArrayList<Integer>();
int mx;
int my;
@SuppressWarnings("rawtypes")
JComboBox tool = new JComboBox();
@SuppressWarnings("unchecked")
public DrawFrame() {
setSize(480, 480);
setTitle("ScratchPad _14");
setLayout(new GridLayout(1,1));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setBackground(Color.WHITE);
setOpacity(1);
tool.addItem("Pen");
tool.addItem("Eraser");
tool.setEnabled(true);
JPanel paintPanel = new PaintPanel();
paintPanel.add(tool);
add(paintPanel);
setVisible(true);
paintPanel.addMouseMotionListener(this);
}
public static void main(String[] args) {
DrawFrame df = new DrawFrame();
}
class PaintPanel extends JPanel
{
public PaintPanel()
{
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g)
{
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
for (int i = 0; i < px.size(); i++) {
g.fillOval(px.get(i), py.get(i), 3, 3);
}
g.setColor(Color.BLUE);
g.drawString("(" + mx + ", " + my + ")", mx + 10, my - 5);
super.paintComponent(g);
}
}
@Override
public void mouseDragged(MouseEvent m) {
int x = m.getX();
int y = m.getY();
mx = x;
my = y;
px.add(x);
py.add(y);
repaint();
}
@Override
public void mouseMoved(MouseEvent m) {
int x = m.getX();
int y = m.getY();
mx = x;
my = y;
}
}
答案 2 :(得分:0)
绘图不应该调用重绘。我已经在mouseDragged中完成了这个,延迟为50毫秒。 然后,默认为双缓冲,因此您不会先在图像中收集所有更改。 擦除也是为一个人完成的。
所以代码变成:
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.BLACK);
for (int i = 0; i < px.size(); i++) {
g.fillOval(px.get(i), py.get(i), 3, 3);
}
g.setColor(Color.BLUE);
g.drawString("(" + mx + ", " + my + ")", mx + 10, my - 5);
}
@Override
public void mouseDragged(MouseEvent m) {
...
repaint(50L);
}
通常会引入一个用于绘画的JPanel,它有一个paintComponent
来覆盖。