为什么repaint不会重绘JPanel中的按钮?

huangapple go评论117阅读模式
英文:

Why doesnt repaint repaint the button in the JPanel?

问题

我不理解 repaint() 如何工作。

我尝试查找教程,但从未找到任何东西,并且“类似问题”的答案也没有真正帮助。

这是我能写的最基本的代码,应该可以工作,但实际上并没有:

static String done = "0";

public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setResizable(false);
    JPanel panel = new JPanel();
    frame.setSize(800, 500);
    frame.setLocation(500, 400);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton end = new JButton(done);
    end.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            done += Integer.valueOf(1);
            panel.repaint();
        }
    });

    panel.add(end);
    frame.add(panel);
    frame.setVisible(true);
}

显然,这只是一个在点击后应该重新绘制的按钮,显示数字+1。

后续问题:
在另一个面板中,如何命令一个面板重新绘制自己?
以下是应该工作的基本代码:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class Repaint
{
    static String done = "0";
    
    public static void main(String[] args)
    {
        new Repaint();
    }
    
    public Repaint()
    {
        createframe();
    }
    
    public void createframe()
    {
        JFrame frame = new JFrame();
        frame.setResizable(false);
        JPanel panel = new JPanel();
        frame.setSize(800, 500);
        frame.setLocation(500, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        Border bo = new LineBorder(Color.black);
        JMenuBar bar = new JMenuBar();
        bar.setBorder(bo);
        JMenu menu = new JMenu("Edit");
        JMenuItem stats = new JMenuItem("Edit the button");
        
        stats.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ev)
            {
                createbox();
            }
        });
        menu.add(stats);
        
        JLabel end = new JLabel(done);
        
        bar.add(menu);
        frame.setJMenuBar(bar);
        panel.add(end);
        frame.add(panel);
        frame.setVisible(true);
    }
    
    public void createbox()
    {
        JFrame framebox = new JFrame();
        framebox.setResizable(false);
        JPanel panelbox = new JPanel();
        framebox.setSize(800, 500);
        framebox.setLocation(500, 400);
        
        JButton end = new JButton(done);
        
        end.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                done += String.valueOf(1);
                framebox.dispose();
            }
        });
        panelbox.add(end);
        framebox.add(panelbox);
        framebox.setVisible(true);
    }
}

基本上,在第二个框架中按下按钮会将字符串“done”的数字增加一。但它不会在原始框架中重新绘制。

英文:

I do not understand how repaint(); works.

I tried to look for a tutorial, but never found anything and the naswers on 'similar questions' also didn't really help.

Here is the most basic code that I could write that should work, but doesn't:

static String done = "0";

	public static void main(String[] args) {
		
		JFrame frame = new JFrame();
		frame.setResizable(false);
		JPanel panel = new JPanel();
		frame.setSize(800, 500);
		frame.setLocation(500, 400);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		
		JButton end = new JButton(done);
		end.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				done += Integer.valueOf(1);
				panel.repaint();
			}
		});
		
		panel.add(ende);
		frame.add(panel);
		frame.setVisible(true);

	}

Obviously this is just a button that should be repainted once clicked with a number+1.

Followup question:
How do I tell a panel to repaint itself while inside another panel?
Here is the base code that should work:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class Repaint
{
    static String done = "0";
    
    public static void main(String[] args)
    {
        new Repaint();
        
    }
    
    public Repaint()
    {
        createframe();
        
    }
    
    public void createframe()
    {
        JFrame frame = new JFrame();
        frame.setResizable(false);
        JPanel panel = new JPanel();
        frame.setSize(800, 500);
        frame.setLocation(500, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        Border bo = new LineBorder(Color.black);
        JMenuBar bar = new JMenuBar();
        bar.setBorder(bo);
        JMenu menu = new JMenu("Edit");
        JMenuItem stats = new JMenuItem("Edit the button");
        
        stats.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ev)
            {
                
                createbox();
                
            }
        });
        menu.add(stats);
        
        JLabel end = new JLabel(done);
        
        bar.add(menu);
        frame.setJMenuBar(bar);
        panel.add(end);
        frame.add(panel);
        frame.setVisible(true);
        
    }
    
    public void createbox()
    {
        JFrame framebox = new JFrame();
        framebox.setResizable(false);
        JPanel panelbox = new JPanel();
        framebox.setSize(800, 500);
        framebox.setLocation(500, 400);
        
        JButton end = new JButton(done);
        
        end.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                done += String.valueOf(1);
                framebox.dispose();
            }
        });
        panelbox.add(end);
        framebox.add(panelbox);
        framebox.setVisible(true);
    }
    
}

Basicially pressing the button in frame 2 increases the number of the String "done" by one. But it does not repaint it in the original frame.

答案1

得分: 1

好的,以下是翻译的内容:

public class Repaint
{
    String done = "0";
    
    JFrame frame;
    JPanel panel;
    Border bo;
    JMenuBar bar;
    JMenu menu;
    JMenuItem stats;
    JLabel endLabel;
    
    JFrame framebox;
    JPanel panelbox;
    JButton endButton;
    
    public static void main(String[] args)
    {
        new Repaint();
    }
    
    public Repaint()
    {
        createFrame();
    }
    
    public void createFrame()
    {
        frame = new JFrame();
        frame.setResizable(false);
        panel = new JPanel();
        frame.setSize(800, 500);
        frame.setLocation(500, 400);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        bo = new LineBorder(Color.black);
        bar = new JMenuBar();
        bar.setBorder(bo);
        menu = new JMenu("Edit");
        stats = new JMenuItem("Edit the button");
        
        stats.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ev)
            {
                createBox();
            }
        });
        menu.add(stats);
        
        endLabel = new JLabel(done);
        
        bar.add(menu);
        frame.setJMenuBar(bar);
        panel.add(endLabel);
        frame.add(panel);
        frame.setVisible(true);
    }
    
    public void createBox()
    {
        framebox = new JFrame();
        framebox.setResizable(false);
        panelbox = new JPanel();
        framebox.setSize(800, 500);
        framebox.setLocation(500, 400);
        
        endButton = new JButton(done);
        
        endButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                done = Integer.toString(Integer.parseInt(done) + 1);
                endButton.setText(done);
                onDispose();
            }
        });
        panelbox.add(endButton);
        framebox.add(panelbox);
        framebox.setVisible(true);
    }
    
    private void onDispose() 
    {
        endLabel.setText(done);
        framebox.dispose();
    }
}

我已经将代码翻译完毕,如有其他需要,请告诉我。

英文:

Ok so I've made an attempt at solving both your questions despite not being entirely sure what you what your program to do.

First off, the answer you accepted is actually wrong. I'm guessing the other commenter forgot that the variable done is actually of the type String, meaning that the operator += doesn't actually do any math, it merely appends the strings. In simpler words, the operator doesn't add 1 to done but it appends the literal string value 1 to done. So if done has value 0 and you click the button with that code, it will append 1 and done will now have the value 01. If you click it again it will build the String 011 and so on.

To fix that little mistake you simply need to parse the String to an Integer and then you can use math operators on it.

Regarding your second problem, I reread your question and your code again and now it seems like I misunderstood in my comment on the other answer. I tried to not change the underlying logic of your code and therefor went off of your code concerning what the JButton does. In your original code, the button increments done and the button is supposed to display that text. The button also is the closing operations of this frame though, since you're calling dispose() in the button's actionPerformed() call.

If that's what's supposed to happen (the button closing the frame on every press), then you don't even need a WindowListener or Override anything, you can simply execute whatever you want to in that actionPerformed() call.

Code:

public class Repaint
{
    String done = "0";
    
    JFrame frame;
    JPanel panel;
    Border bo;
    JMenuBar bar;
    JMenu menu;
    JMenuItem stats;
    JLabel endLabel;
    
    JFrame framebox;
    JPanel panelbox;
    JButton endButton;
    
    public static void main(String[] args)
    {
        new Repaint();
        
    }
    
    public Repaint()
    {
        createFrame();
    }
    
    public void createFrame()
    {
        frame = new JFrame();
        frame.setResizable(false);
        panel = new JPanel();
        frame.setSize(800, 500);
        frame.setLocation(500, 400);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        bo = new LineBorder(Color.black);
        bar = new JMenuBar();
        bar.setBorder(bo);
        menu = new JMenu("Edit");
        stats = new JMenuItem("Edit the button");
        
        stats.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ev)
            {
                
                createBox();
                
            }
        });
        menu.add(stats);
        
        endLabel = new JLabel(done);
        
        bar.add(menu);
        frame.setJMenuBar(bar);
        panel.add(endLabel);
        frame.add(panel);
        frame.setVisible(true);
        
    }
    
    public void createBox()
    {
        framebox = new JFrame();
        framebox.setResizable(false);
        panelbox = new JPanel();
        framebox.setSize(800, 500);
        framebox.setLocation(500, 400);
        
        endButton = new JButton(done);
        
        endButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                done = Integer.toString(Integer.parseInt(done) + 1);
                endButton.setText(done);
                onDispose();
            }
        });
        panelbox.add(endButton);
        framebox.add(panelbox);
        framebox.setVisible(true);
    }
    
    private void onDispose() 
    {
        endLabel.setText(done);
        framebox.dispose();
    }
}

I ended up replacing all your local variables with class variables (perhaps you don't need all of them to be non-local, but whatever) so you can actually call the JFrame instance frame outside of the createFrame() method.

You can see the calls of toString() and parseInt() to actually get the math operator to work.

endButton.addActionListener(new ActionListener()
{
    @Override
    public void actionPerformed(ActionEvent e)
    {
        done = Integer.toString(Integer.parseInt(done) + 1);
        endButton.setText(done);
        onDispose();
    }
});

Next I simply replaced the direct call of JFrame.dispose() and added a little onDispose() method, in which I update (by calling setText()) the Label. In this method you can now basically add anything that's supposed to happen before the call of dispose().

private void onDispose() 
{
    endLabel.setText(done);
    framebox.dispose();
}

If this is not what you're looking for let me know.

答案2

得分: 0

如果您想要将JButton上的数字增加1并显示出来,则无需使用repaint()方法。

这与此无关。

相反,您只需使用setText()方法。

代码:

JButton end = new JButton(done);
end.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        done = done + "1";
        end.setText(done);
    }
});

repaint()方法与Java中的Graphics/Graphics2D相关。当我们想要更改组件的外观时,会调用此方法。

英文:

If you want to add 1 to the number on JButton and show it, then there is no need to use repaint() method.

It is irrelevant.

Instead you can just use setText() method.

Code:

JButton end = new JButton(done);
end.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
done = done + "1";
end.setText(done);
}
});

> repaint() method is related to Graphics/Graphics2D in Java. It is called when we want to change the look of a component.

huangapple
  • 本文由 发表于 2020年6月29日 15:16:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/62633027.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定