我正在尝试为学习目的创建一个简单的键盘和显示程序。我有它工作,但我想知道是否有更好的方式与不同类中的对象进行交互。
我创建了一个名为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);
}
}
答案 0 :(得分:2)
构造显示面板,然后将其作为参数传递给键盘面板的构造函数。然后,构造函数将显示面板存储在实例字段(属性)中,并且侦听器将使用此属性来调用setDisplay
方法。当然,setDisplay
和clearDisplay
方法(以及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");