我正在编写一个非常大整数的乘法应用程序,我需要在Swing组件中更新乘法的每个sigle步骤(我创建了一个带有JTextArea的JPane扩展类,然后将它添加到ScrollPane中的JFrame )。问题是这个Swing组件只在乘法算法完成后才更新。我尝试使用一个可以每10毫秒调用一次Pane重绘方法的Thread,但它没有用。接下来是问题的一个例子。
这是主要的Frame类:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Frame extends JFrame implements ActionListener{
private Console console;
private JButton calculate;
private Calculator calculator;
public Frame(){
console=new Console();
calculate=new JButton("Calculate");
calculate.addActionListener(this);
calculate.setActionCommand("");
calculator=new Calculator(this);
this.setLayout(new BorderLayout());
this.add(console,BorderLayout.CENTER);
this.add(calculate, BorderLayout.NORTH);
this.setTitle("Frame");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(new Dimension(500,500));
this.setLocationRelativeTo(null);
}
public void writeOnConsole(String txt){
console.write(txt);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals("")){
console.clear();
calculator.calculate();
}
}
public static void main(String[] args) {
new Frame();
}
}
这是控制台类
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
public class Console extends JPanel{
private JTextArea area;
public Console(){
this.setBorder(new TitledBorder("Console:"));
area=new JTextArea();
this.setLayout(new BorderLayout());
JScrollPane scroll=new JScrollPane(area);
this.add(scroll,BorderLayout.CENTER);
}
public void clear(){
area.setText("");
}
public void write(String txt){
area.append(txt+"\n");
}
}
最后,这是Calculator类(负责调用写作的人)
public class Calculator {
private Frame parent;
public Calculator(Frame f){
parent=f;
}
public void calculate(){
for (int i = 0; i <= 1000000; i++) {
parent.writeOnConsole("Iteration "+i);
}
}
}
请注意,如果您运行该程序,GUI将冻结,直到Calculator类完成循环。
答案 0 :(得分:0)
如果您的布局类似于BorderLayout
,并且您希望在JFrame中更新它,请执行以下操作
JFrame frame = new JFrame();
BorderLayout layout = new BorderLayout();
layout.layoutContainer(frame.getContentPane());// use the frame as the border layout container
否则你可以使用JFrame pack()方法。 pack方法根据组件的首选大小打包窗口中的组件。它不是用于更新,而是更新JFrame,这是一种技巧
JFrame frame = new JFrame();
//change the components dynamically
frame.pack();
或使用Container methdod validate()。验证容器意味着布置其子组件。与布局相关的更改,例如设置组件的边界或将组件添加到容器中。
JFrame frame = new JFrame();
Container container = frame.getContentPane();
container.validate();
或者如果您想更新特定组件,请使用
Component component = new JPanel();
component.repaint();
如果此组件是轻量级组件,则repaint()方法会尽快调用此组件的paint方法。
或者如果您想要例如动态地逐个发生许多变化,那么您可以使用下面的代码,这与我上面提到的内容完全不同。为此,您可以在另一个线程中使用platform.runlater()
来处理即将实时更改的所有内容
new Thread(new Runnable()
{
@Override
public void run()
{
Platform.runLater(new Runnable()//use platform.runlater if you are using javafx
{
@Override
public void run()
{
try
{Thread.sleep(50);}catch(Exception e){}//use it in for loop where changes happen
//do some realtime change of components
}
});
}).start();
答案 1 :(得分:0)
尝试使用update方法调用paint方法来维护每个更改
答案 2 :(得分:0)
您的控制台类将是
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
public class Console extends JPanel{
private JTextArea area;
public Console(){
this.setBorder(new TitledBorder("Console:"));
area=new JTextArea();
this.setLayout(new BorderLayout());
JScrollPane scroll=new JScrollPane(area);
this.add(scroll,BorderLayout.CENTER);
}
public void clear(){
area.setText("");
}
public void write(String txt){
area.append(txt+" "+"\n");
}
}
并且Calculator类是
public class Calculator {
private Frame parent;
public Calculator(Frame f){
parent=f;
}
public void calculate(){
new Thread(new Runnable() {
@Override
public void run()
{
for (int i = 0; i <= 100; i++) {
try
{
Thread.sleep(50);
}
catch(Exception e)
{
e.printStackTrace();
}
parent.writeOnConsole("Iteration "+i);
}
}
}).start();
}
}
正如您所见,我使用另一个线程进行更改