[英]Java: Repaint in Swing Not Working
我正在學習Java swing,並且無法使用以下程序。 它創建一個小框架,頂部有一個退出按鈕。 目的是在單擊鼠標的任何地方顯示坐標。 當我單擊鼠標時2發生了不需要的事情:
在此討論基礎上,我在進行repaint()
revalidate()
之前使用了removeAll()
和revalidate()
,但這沒有幫助。 這段代碼是從這里獲取的,用來對在線文檔進行研究的原因代碼。
有指針嗎?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.BorderLayout;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
public class QuitCoordinateTest {
public static void main(String[] args){
GUI gui = new GUI();
}
}
class MyFrame extends JFrame implements ActionListener{
int clickX;
int clickY;
public void paint(Graphics g){
g.drawString("" + clickX + ", " + clickY, clickX, clickY);
}
public void actionPerformed(ActionEvent e){
System.exit(0);
}
}
//=======================================================//
class GUI extends MyFrame {
JButton quitButton = new JButton("Quit");
public GUI(){
MyFrame displayWindow = new MyFrame();
displayWindow.setTitle("Title");
/*
JPanel buttonPanel = new JPanel();
buttonPanel.add(quitButton);
displayWindow.getContentPane().add(buttonPanel,BorderLayout.NORTH);
JPanel textPanel = new JPanel();
*/
displayWindow.getContentPane().add(quitButton,BorderLayout.NORTH);
quitButton.addActionListener(displayWindow);
displayWindow.setSize(201,201);
displayWindow.setVisible(true);
// displayWindow.pack();
displayWindow.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
displayWindow.addMouseListener(new MouseProc(displayWindow));
}//end constructor
}//end class GUI definition
//=======================================================//
//This listener class monitors for mouse presses and
// displays the coordinates of the mouse pointer when the
// mouse is pressed on the source object.
class MouseProc extends MouseAdapter{
MyFrame refToWin;
MouseProc(MyFrame inWin){
refToWin = inWin;
}
//Override the mousePressed method to determine and
// display the coordinates when the mouse is pressed.
public void mousePressed(MouseEvent e){
refToWin.removeAll();
refToWin.clickX = e.getX();
refToWin.clickY = e.getY();
//Force the JFrame object to be repainted in order to
// display the coordinate information.
refToWin.removeAll();
refToWin.validate();
refToWin.repaint();
}
}
repaint()
工作正常。 protected void paintComponent(Graphics g)
繪制protected void paintComponent(Graphics g)
方法重寫,然后將其顯示在JFrame中。 paintComponent(g)
的paintComponent(g)
方法-這將擦除舊圖像,這是問題之一的原因。 removeAll()
即可-刪除所有組件,包括按鈕。 你怎么叫這個 您確定要調用此方法嗎? 例如,類似...
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
String str = String.format("[%d, %d]", clickX, clickY);
g.drawString(str, clickX, clickY);
}
public int getClickX() {
return clickX;
}
public void setClickX(int clickX) {
this.clickX = clickX;
}
public int getClickY() {
return clickY;
}
public void setClickY(int clickY) {
this.clickY = clickY;
}
例如
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class DetectClicks extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 650;
private int clickX;
private int clickY;
public DetectClicks() {
MyMouseListener mouseAdapter = new MyMouseListener(this);
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter); // to allow dragging!
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
String str = String.format("[%d, %d]", clickX, clickY);
g.drawString(str, clickX, clickY);
}
public int getClickX() {
return clickX;
}
public void setClickX(int clickX) {
this.clickX = clickX;
}
public int getClickY() {
return clickY;
}
public void setClickY(int clickY) {
this.clickY = clickY;
}
private static void createAndShowGui() {
DetectClicks mainPanel = new DetectClicks();
JFrame frame = new JFrame("DetectClicks");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyMouseListener extends MouseAdapter {
private DetectClicks detectClicks;
public MyMouseListener(DetectClicks detectClicks) {
this.detectClicks = detectClicks;
}
@Override
public void mousePressed(MouseEvent evt) {
showPoint(evt);
}
@Override
public void mouseDragged(MouseEvent evt) {
showPoint(evt);
}
private void showPoint(MouseEvent evt) {
detectClicks.setClickX(evt.getX());
detectClicks.setClickY(evt.getY());
detectClicks.repaint();
}
}
您的事件被打印坐標的處理程序占用,您需要重新分發該事件,以便按鈕可以看到它。 您可以在座標顯示事件處理常式中執行以下操作:
Component c = e.getComponent();
c.getParent().dispatchEvent( e );
另外,我很想使用框架的玻璃窗格,並用坐標將JLabel放在上面,而不是弄亂繪畫方法。
您不必使用任何repaint(),invalidate()等。我強烈建議您使用
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//TODO udpdate UI compontents, layouts etc.
}
});
這樣可以確保UI組件實時更新。 因為我們不知道系統何時更新UI層次結構,所以我們無法強制執行。 這使系統可以自行確定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.