Java GUI:跨不同JFrame共享值

时间:2009-10-15 18:08:22

标签: java user-interface

我正在编写一些实验性的GUI代码。我正在尝试设置它,因此调用main会生成两个窗口,每个窗口都有一个按钮和一个标签。标签显示按钮被点击的次数。但是,我想要它,如果你在一个窗口中单击按钮,其他更新中的标签。我该怎么做?

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

@SuppressWarnings("serial")
public class TestGUI extends JFrame {

    private static int count;
    private JButton button = new JButton("odp"); 
    private JLabel label = new JLabel();

    public TestGUI() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        add(button);
        setLayout(new FlowLayout(FlowLayout.RIGHT));

        labelUpdateText();
        add(label);

        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                count++;
                labelUpdateText();
            }
        });

        pack();
        setVisible(true);
    }

    private void labelUpdateText() {
        label.setText("Count: " + count);
    }

    public static void main(String[] args) {
        new TestGUI();
        new TestGUI();
    }

}

5 个答案:

答案 0 :(得分:4)

1 - 我宁愿避免扩展JFrame,因为你并没有真正创建一个新的JFrame类。

因此,不是将整个类作为JFrame的子类(不是),而是可以创建它们的实例而不添加更多行为。

2 - 如果你想要有两个反映同一“事物”价值的标签,你必须分享他们之间的东西(或让某人为你更新那个值)

所以,使用您需要的着名MVC

  • 模型您要在两个标签中显示的计数器。

  • 查看显示模型的标签

  • 控制器在他们之间处理的事情。

它们都属于应用程序,它们是应用程序的实例属性。

要了解它们如何组合在一起我在这里粘贴代码:

import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.*;

 // TwoWindows is the Application 
public class TwoWindows {
    // shared state ( model ) 
    private int clickCount = 0;

    // UI
    private List<JLabel> toUpdate = new ArrayList<JLabel>();

    // listener ( listens for clicks on buttons kind of controller  )
    private ActionListener actionListener = new ActionListener() {

        // Each time update the UI 
        public void actionPerformed( ActionEvent e ) {
            clickCount++; 
            for( JLabel label : toUpdate ) {
                label.setText( "Count: " + ( clickCount ) );
            }
        }
    };

    // Createsa winddow with a label and a button
    public void showWindow( String named ) {
        JFrame f = new JFrame( named );
        f.add( createButtonAndLabel() );
        f.pack();
        f.setVisible( true );
    }

    // Creates the label and button and adds this.actionListener
    // to each button. 
    private JComponent  createButtonAndLabel() {
        JPanel panel = new JPanel();
        JLabel label =  new JLabel("Count: 0");
        JButton clickMe = new JButton("Click me");
        // adding the label to a "view" list.
        toUpdate.add( label );
        // adding the listener to each button 
        clickMe.addActionListener( actionListener );
        panel.add( label );
        panel.add( clickMe );
        return panel;
    }

    // Run the app
    public static void main( String [] args ) {
        TwoWindows t = new TwoWindows();
        t.showWindow("A");
        t.showWindow("B");
    }
 }

通过这种方式,您可以拥有共享模型并根据需要更新任意数量的视图。

alt text http://img387.imageshack.us/img387/1106/capturadepantalla200910d.png

答案 1 :(得分:1)

您将需要设置一个eventListener并让按钮触发一个更新共享变量的事件(AtomicInteger会想到)并在事件被捕获时更新按钮文本。

答案 2 :(得分:1)

我首先不要扩展JFrame并避免使用可变的静态。

最简单的方法是将建筑分解为阶段。首先创建两个标签。然后构建其余部分。为每个帧调用两次构造函数方法,每次都将标签作为不同的参数。

更复杂的是拥有一个模型。动作侦听器(控制器)更新模型,模型触发状态更改事件,与另一帧中的标签关联的更改侦听器(视图)侦听。

答案 3 :(得分:0)

你可以这样做:

主要方法:

TestGUI a, b;
a = new TestGUI(b);
b = new TestGUI(a);

然后添加到构造函数:

public TestGUI(TestGUI other)

然后从任一GUI执行:

other.labelUpdateText();

答案 4 :(得分:0)

你真的需要2个JFrame吗?

你可以改为拥有一个主服务器和一个服务器:一个可以是JFrame,另一个可以是非模态对话框。

(非模态,以便它不会偷走并保持焦点,直到它被最小化)