Java Swing之谜:什么没有';第一次迭代是否显示在JPanel上?
这里有一个我已经接近了解,但从来没有真正了解 下面列出的代码应该在看到第一次单击时立即绘制一个绿色圆圈。没有。后续单击以红色绘制将当前单击点与上一点连接的线。代码在第一次单击时失败,并在随后的所有单击中起作用。为什么第一次单击不显示?它跑了 我做错了什么 代码应该在任何当前JDE上编译 短暂性脑缺血发作Java Swing之谜:什么没有';第一次迭代是否显示在JPanel上?,java,swing,graphics,initialization,Java,Swing,Graphics,Initialization,这里有一个我已经接近了解,但从来没有真正了解 下面列出的代码应该在看到第一次单击时立即绘制一个绿色圆圈。没有。后续单击以红色绘制将当前单击点与上一点连接的线。代码在第一次单击时失败,并在随后的所有单击中起作用。为什么第一次单击不显示?它跑了 我做错了什么 代码应该在任何当前JDE上编译 短暂性脑缺血发作 从demolines() 并添加canvas.addMouseListener(这个) 我做错了什么 您正在使用getGraphics进行自定义绘制。调用重新绘制时,以前的任何绘制都将丢失。相反
从
demolines()
并添加canvas.addMouseListener(这个)函数末尾的代码>
我做错了什么
您正在使用getGraphics
进行自定义绘制。调用重新绘制时,以前的任何绘制都将丢失。相反,将所有自定义绘制功能移动到基于JComponent
或JPanel
的新类中,并在其中重写。请记住调用super.paintComponent(g)
有关从paintComponent
中绘制多个组件的解决方案,请参见。您可以构建自定义可绘制组件的列表
,从方法中迭代列表,并根据需要使用drawLine
或drawOval
。重写paintComponent()时,应始终将super.paintComponent()
作为第一行调用
该代码存在大量问题。我修复了它们,但忽略了记录每个更改。仔细查看此代码,如果您不理解(通过阅读相关文档/教程)我为什么进行更改,请提出问题
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.EmptyBorder;
public class Demo extends JPanel
implements ListSelectionListener, MouseListener {
int clkCt = 0, // Count of the number of clicks we've done.
oldX, // Penultimate X value
oldY, // Penultimate X value
scrH = 100, // Height of the drawing canvas.
scrW = 400; // Width of the drawing canvas.
JLabel ctL; // Displays the number of clicks we've done.
int x, y;
public void demoLines() {
oldX = scrH / 2;
oldY = oldX;
// Create a panel
setBackground(Color.black);
setForeground(Color.red);
setPreferredSize(new Dimension(scrW, scrH));
// Create the label for the click count.
ctL = new JLabel("None Yet");
ctL.setBackground(Color.black);
ctL.setForeground(Color.red);
ctL.setBounds((scrH / 15), (scrH * 13 / 15), (scrW / 15), (scrH / 15));
add(ctL);
addMouseListener(this);
}
public void mouseClicked(MouseEvent m) {
// Where was the mouse clicked?
x = m.getX();
y = m.getY();
repaint();
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
public void paintComponent(Graphics g) {
// This always runs.
ctL.setText(clkCt + "");
if (clkCt == 0) {
// This never displays!
g.setColor(Color.green);
int r = scrH * 4 / 5;
g.drawOval((scrH / 10), (scrH / 10), r, r);
}
g.setColor(Color.red);
g.drawLine(oldX, oldY, x, y);
oldX = x;
oldY = y;
clkCt++;
}
public void valueChanged(ListSelectionEvent event) {
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
Demo m = new Demo();
m.demoLines();
JFrame f = new JFrame("Demo");
f.add(m);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
笔记
不要延伸框架或其他顶级容器。而是创建并使用一个实例李>
javagui可能必须在许多平台上工作,在不同的屏幕分辨率上&使用不同的plaf。因此,它们不利于部件的精确放置。要为健壮的GUI组织组件,请使用布局管理器或它们的组合,以及空白的布局填充和边框李>
在paintComponent(Graphics)
方法中添加JPanel
&进行自定义绘制,而不是在顶级容器(如JFrame
)中进行绘制。还要为自定义构件返回合理的首选尺寸,以帮助布局管理器李>
对于JComponent
中的自定义绘制,请替代paintComponent(Graphics)
,而不是paint(Graphics)
“。当您重写paintComponent()
时”是的,您应该这样做,但是如果您仔细查看代码,您可能会注意到它不会重写该方法,因为1)它包含比常用方法更多的参数,2)JFrame
没有paintComponent(Graphics)
方法!成功了!又好又容易。谢谢谢谢你的密码。它可以工作,但不会改变背景色。这对于我正在进行的更大的项目很重要。当我把JPanel放进相框时,颜色变了。
Graphics g = canvas.getGraphics();
if (g == null) {
System.out.println("No graphics for canvas!");
} else {
canvas.revalidate(); // This didn't help.
paintComponent(g, (oldX + oldX / 2), (oldY + oldY / 2));
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.EmptyBorder;
public class Demo extends JPanel
implements ListSelectionListener, MouseListener {
int clkCt = 0, // Count of the number of clicks we've done.
oldX, // Penultimate X value
oldY, // Penultimate X value
scrH = 100, // Height of the drawing canvas.
scrW = 400; // Width of the drawing canvas.
JLabel ctL; // Displays the number of clicks we've done.
int x, y;
public void demoLines() {
oldX = scrH / 2;
oldY = oldX;
// Create a panel
setBackground(Color.black);
setForeground(Color.red);
setPreferredSize(new Dimension(scrW, scrH));
// Create the label for the click count.
ctL = new JLabel("None Yet");
ctL.setBackground(Color.black);
ctL.setForeground(Color.red);
ctL.setBounds((scrH / 15), (scrH * 13 / 15), (scrW / 15), (scrH / 15));
add(ctL);
addMouseListener(this);
}
public void mouseClicked(MouseEvent m) {
// Where was the mouse clicked?
x = m.getX();
y = m.getY();
repaint();
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
public void paintComponent(Graphics g) {
// This always runs.
ctL.setText(clkCt + "");
if (clkCt == 0) {
// This never displays!
g.setColor(Color.green);
int r = scrH * 4 / 5;
g.drawOval((scrH / 10), (scrH / 10), r, r);
}
g.setColor(Color.red);
g.drawLine(oldX, oldY, x, y);
oldX = x;
oldY = y;
clkCt++;
}
public void valueChanged(ListSelectionEvent event) {
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
Demo m = new Demo();
m.demoLines();
JFrame f = new JFrame("Demo");
f.add(m);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}