Java 如何在main中的runnable之外对JFrame GUI进行更改?
我目前正在学习JavaGUI,我正在制作一个Java程序,您可以在GUI中编辑带有文本的形状。我创建了一个Java 如何在main中的runnable之外对JFrame GUI进行更改?,java,swing,user-interface,canvas,Java,Swing,User Interface,Canvas,我目前正在学习JavaGUI,我正在制作一个Java程序,您可以在GUI中编辑带有文本的形状。我创建了一个JFrame,其中包含一个自定义MyCanvas对象和一个文本字段。其思想是,MyCanvas对象有一个MouseListener,并将包含形状,单击这些形状将启用GUI中的文本字段,以便用户可以输入要在形状中显示的新消息。但是,我在GUI类的主方法中使用Runnable运行GUI,并且我无法从MyCanvas类启用文本框,因为它在Runnable之外。有人能帮我怎么做到这一点吗 以下是我的
JFrame
,其中包含一个自定义MyCanvas
对象和一个文本字段。其思想是,MyCanvas
对象有一个MouseListener
,并将包含形状,单击这些形状将启用GUI中的文本字段,以便用户可以输入要在形状中显示的新消息。但是,我在GUI类的主方法中使用Runnable
运行GUI,并且我无法从MyCanvas
类启用文本框,因为它在Runnable
之外。有人能帮我怎么做到这一点吗
以下是我的代码(伪代码)的基本结构:
//GUI类
公共类GUI扩展JFrame实现ActionListener{
私有静态MyCanvas c=new MyCanvas();//画布
私有静态文本字段编辑器=新建文本字段();//文本字段
公共静态void init(){
//初始化GUI元素并禁用文本框
}
公共静态void enableTextBox(){
//启用文本字段
}
公共静态无效disableTextBox(){
//禁用文本字段
}
已执行的公共无效操作(操作事件e){
//从文本框中获取消息
}
公共静态void main(字符串[]args){
//运行GUI框架
javax.swing.SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
init();
/*添加一个RectTextBox(一个包含文本的矩形对象,
*类(在别处定义)
*/
c、 addShape(新文本框(“Hello World”);
}
}
}
}
//画布类
类MyCanvas扩展JPanel实现MouseListener{
//画布上块的ArrayList
ArrayList块=新的ArrayList();
//执行器
公共MyCanvas(){
//初始化画布并将MouseListener添加到此画布
}
公共组件(图形g){
//在画布上绘制所有块
}
公共void addShape(矩形文本框b){
//将文本框b添加到块阵列列表
}
公共无效mouseClicked(MouseEvent e){
//检查是否单击了ArrayList中的任何块
/*启用GUI中的文本字段以输入消息,然后设置
*输入到块中的消息
*/
}
}
因此,您有了一个良好的开端。MyCanvas
具有其他类可以调用的功能,例如,addShape
// Canvas class
class MyCanvas extends JPanel implements MouseListener {
// ArrayList of blocks on the canvas
ArrayList<RectTextBox> blocks = new ArrayList<RectTextBox>();
// Ctor
public MyCanvas() {
// Initialize canvas and add MouseListener to this canvas
}
public void paintComponent(Graphics g) {
// Paints all blocks on canvas
}
public void addShape(RectTextBox b) {
// Adds the text box b to the blocks ArrayList
}
public void mouseClicked(MouseEvent e) {
// check if any blocks from the ArrayList is clicked
/* enables the text field from GUI to enter messages, then set the
* message entered to the block
*/
}
}
然后,当EditorPane
想要进行更改时,它可以使用canvas
调用所需的方法
然后,我们构建您的UI,您将创建一个MyCanvas
的实例,将该引用传递到EditorPane
并将其添加到UI中,例如
public class EditorPane extends JPanel {
private MyCanvas canvas;
public EditorPane(MyCanvas canvas) {
this.canvas = canvas;
// Build UI as required
}
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MyCanvas canvas = new MyCanvas();
EditorPane editor = new EditorPane(canvas);
JFrame frame = new JFrame();
frame.add(canvas);
frame.add(editor, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
现在,就我个人而言,我会将大部分内容折叠到
界面
,以防止EditorPane
对MyCanvas
做更多的事情,但这是另一天的主题;)要做的第一件事是,远离静态
,它在这里对您的应用程序没有帮助。下一件事是在您的MyCanvas
和控制类之间维护一个引用。然后,您可以在MyCanvas
中提供控制器类可以调用的功能(例如设置要使用的形状类型)非常感谢!使用您的解决方案,有没有办法让画布也了解编辑器面板?我想让编辑器面板只在您单击其中一个形状时打开。可能不值得努力。我只想让它在您单击形状时,它所做的一件事“打开”画布
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MyCanvas canvas = new MyCanvas();
EditorPane editor = new EditorPane(canvas);
JFrame frame = new JFrame();
frame.add(canvas);
frame.add(editor, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});