Java与不同类中的对象交互

时间:2011-10-20 14:33:37

标签: java

我正在尝试为学习目的创建一个简单的键盘和显示程序。我有它工作,但我想知道是否有更好的方式与不同类中的对象进行交互。

我创建了一个名为KeypadPanel的类,它是一个带有网格布局的面板,并且我的所有按钮都被添加到它中。然后我创建了一个ActionListener并将其附加到按钮上,每个按钮都有事件。然后我将此面板添加到边框布局面板的中心。

然后我创建了一个DisplayPanel类来保存添加到边框布局面板北部的标签。但是我仍然是新的并且学习Java,所以我可以与DisplayPanel中的标签进行交互的唯一方法是使标签为static而setDisplay方法是静态的。然后我可以在ButtonListener中调用它们并更改显示。

这是键盘,显示器和主类的代码

public class KeypadPanel extends JPanel {

// setup button objects
private JButton b1 = new JButton("1");
private JButton b2 = new JButton("2");
private JButton b3 = new JButton("3");
private JButton b4 = new JButton("4");
private JButton b5 = new JButton("5");
private JButton b6 = new JButton("6");
private JButton b7 = new JButton("7");
private JButton b8 = new JButton("8");
private JButton b9 = new JButton("9");
private JButton b0 = new JButton("0");
private JButton bStar = new JButton("*");
private JButton bPound = new JButton("#");

public KeypadPanel() {

    // setup panel
    setLayout(new GridLayout(4, 3));
    setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.black));

    setPreferredSize(new Dimension(150, 150));

    // add listeners to buttons
    b1.addActionListener(new ButtonListener());
    b2.addActionListener(new ButtonListener());
    b3.addActionListener(new ButtonListener());
    b4.addActionListener(new ButtonListener());
    b5.addActionListener(new ButtonListener());
    b6.addActionListener(new ButtonListener());
    b7.addActionListener(new ButtonListener());
    b8.addActionListener(new ButtonListener());
    b9.addActionListener(new ButtonListener());
    b0.addActionListener(new ButtonListener());
    bStar.addActionListener(new ButtonListener());
    bPound.addActionListener(new ButtonListener());

    // add buttons to panel
    add(b1);
    add(b2);
    add(b3);
    add(b4);
    add(b5);
    add(b6);
    add(b7);
    add(b8);
    add(b9);
    add(bPound);
    add(b0);
    add(bStar);

}

// setup listener for buttons
private class ButtonListener implements ActionListener {

    public void actionPerformed(ActionEvent e) {

        // determine which button raised event and call setDisplay
        if (e.getSource() == b1) {
            DisplayPanel.setDisplay("1");
        } else if (e.getSource() == b2) {
            DisplayPanel.setDisplay("2");
        } else if (e.getSource() == b3) {
            DisplayPanel.setDisplay("3");
        } else if (e.getSource() == b4) {
            DisplayPanel.setDisplay("4");
        } else if (e.getSource() == b5) {
            DisplayPanel.setDisplay("5");
        } else if (e.getSource() == b6) {
            DisplayPanel.setDisplay("6");
        } else if (e.getSource() == b7) {
            DisplayPanel.setDisplay("7");
        } else if (e.getSource() == b8) {
            DisplayPanel.setDisplay("8");
        } else if (e.getSource() == b9) {
            DisplayPanel.setDisplay("9");
        } else if (e.getSource() == b0) {
            DisplayPanel.setDisplay("0");
        } else if (e.getSource() == bStar) {
            DisplayPanel.setDisplay("*");
        } else if (e.getSource() == bPound) {
            DisplayPanel.setDisplay("#");
        } else {
            return;
        }
    }

}

------------

}
public class DisplayPanel extends JPanel {

// setup display label object
private static JLabel display = new JLabel("");

public DisplayPanel() {

    // setup panel and add label
    setPreferredSize(new Dimension(200, 25));
    setBorder(BorderFactory.createLineBorder(Color.black, 3));
    add(display);

}
/**
 * @param incoming
 *            the text to add to the display
 */
public static void setDisplay(String incoming) {

    // get the incoming string and add to existing display string

    String current, changed;

    current = display.getText();
    changed = current.concat(incoming);
    display.setText(changed);

}
/**
 * 
 * clears the current text from the display
 */
public static void clearDisplay() {
    // clears display
    display.setText("");

}
}
-----------------
public class KeypadTest {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    //setup frame
    JFrame frame = new JFrame ("Keypad Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //setup main panel and layout
    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout(3, 3));

    //create panel objects to fill frame and panel
    KeypadPanel keypad = new KeypadPanel();
    ClearPanel clear = new ClearPanel();
    DisplayPanel display = new DisplayPanel();

    // add to main panel
    panel.add(display, BorderLayout.NORTH);
    panel.add(keypad, BorderLayout.CENTER);
    panel.add(clear, BorderLayout.EAST);


    // setup frame
    frame.getContentPane().add(panel);
    frame.pack();
    frame.setVisible(true);
}

}

3 个答案:

答案 0 :(得分:2)

构造显示面板,然后将其作为参数传递给键盘面板的构造函数。然后,构造函数将显示面板存储在实例字段(属性)中,并且侦听器将使用此属性来调用setDisplay方法。当然,setDisplayclearDisplay方法(以及label字段)不应该是静态的。想一想:如果您的应用程序需要两个不同的DisplayPanel实例?

,它将如何运作?

请注意,您的代码可以在其他方面得到增强。例如,您只能创建ButtonListener的一个实例,并将此唯一实例添加为每个按钮的侦听器。

几乎永远不会调用

setPreferredSize:首选大小由布局管理器根据面板的组件自动计算。

最后,main方法中的所有代码都应该在事件派发线程中运行,使用SwingUtilities.invokeLater

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        // put the main code here
    }
});

答案 1 :(得分:0)

要与其他类中的对象进行交互,您必须将其声明为public而不是private

public JButton b1 = new JButton("1");

答案 2 :(得分:0)

您可能需要考虑使用依赖注入。它有点先进,但一旦你得到它,它比用于施工参数更通用,更灵活和方便。

最简单的方法是将java spring添加到类路径(google for that),然后使用在应用程序启动时加载的 application-context.xml 文件(见下文)你的bean,特别是(例如@Component)注释类。

现在Spring将为您处理对象管理。您不需要创建或处理它们,最重要的是,您可以随意将它们注​​入:

    @Component     
    public class DisplayPanel extends JPanel {


        private JLabel display = new JLabel("");

        public DisplayPanel() {
            // ...
        }
        public void setDisplay(String value){
            this.display.setText(value);
        }
    }

    @Component
    public class ButtonListener implements ActionListener {

        @Inject
        private DisplayPanel displayPanel;

        public void actionPerformed(ActionEvent e) {

            if (e.getSource() == b1) {
                displayPanel.setDisplay("1");
            // ...
            }
        }
    }

简单的application-context.xml:

<beans xmlns="http://www.springframework.org/schema/beans" 

    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    default-autowire="byName">

    <context:annotation-config />
    <!-- scan your package for annotated class -->
    <context:component-scan base-package="your.base.package.name" />

</beans>

启动时加载:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:application-context.xml");