从外部访问JFrame内容 [英] Accessing JFrame stuff from the outside

查看:113
本文介绍了从外部访问JFrame内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

真的,这里真的很愚蠢的问题。我是Java(和OOP)的新手,来自一个Javascript(Extendscript,实际上)背景。我在这里有一个JFrame:

  package info.chrismcgee.sky.production; 

import java.awt.EventQueue;
import java.awt.Font;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;

import net.miginfocom.swing.MigLayout;

import org.jdesktop.swingx.JXTreeTable;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;

public class ProductionWindow extends JFrame {

/ **
*
* /
private static final long serialVersionUID = -1899673458785493250L;
private JPanel contentPane;
private JTextField textField;
private JLabel lblTodaysDate;
私有JXTreeTable treeTable;

/ **
*创建框架。
* /
public ProductionWindow(){
setMinimumSize(new Dimension(450,300));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,450,300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5,5));
setContentPane(contentPane);
contentPane.setLayout(new MigLayout(,[] [grow,center] [],[] [grow] []));

JButton btnPrev = new JButton(< - PREV);
contentPane.add(btnPrev,cell 0 0,alignx left);

lblTodaysDate = new JLabel(今日日期);
lblTodaysDate.setHorizo​​ntalAlignment(SwingConstants.CENTER);
lblTodaysDate.setFont(new Font(Lucida Grande,Font.PLAIN,20));
contentPane.add(lblTodaysDate,cell 1 0,growx);

JButton btnNext = new JButton(NEXT - >);
contentPane.add(btnNext,cell 2 0,alignx right);

treeTable = new JXTreeTable();
treeTable.setBorder(new EtchedBorder(EtchedBorder.LOWERED,null,null));
contentPane.add(treeTable,cell 0 1 3 1,grow);

JLabel lblTotal = new JLabel(Total:);
lblTotal.setFont(new Font(Lucida Grande,Font.PLAIN,24));
contentPane.add(lblTotal,cell 0 2);

textField = new JTextField();
textField.setEditable(false);
textField.setHorizo​​ntalAlignment(SwingConstants.RIGHT);
textField.setFont(new Font(Lucida Grande,Font.PLAIN,24));
textField.setText(1,000);
contentPane.add(textField,cell 1 2 2 1,growx);
textField.setColumns(10);
}

public JPanel getContentPane(){
return contentPane;
}

public void setContentPane(JPanel contentPane){
this.contentPane = contentPane;
}

public JTextField getTextField(){
return textField;
}

public void setTextField(JTextField textField){
this.textField = textField;
}

public JLabel getLblTodaysDate(){
return lblTodaysDate;
}

public void setLblTodaysDate(String today){
this.lblTodaysDate.setText(today);
}

public JXTreeTable getTreeTable(){
return treeTable;
}
}

然后我从一个 Main class:

  package info.chrismcgee.sky.production; 

import info.chrismcgee.sky.production.tables.JobManager;
import info.chrismcgee.sky.production.tables.ShowJobs;
import info.chrismcgee.util.InputHelper;

import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.apache.commons.io.FileUtils;
import org.joda.time.LocalDate;

public class Main {

//这个枚举将调用一个存储过程,它返回某一天的所有作业。
public static final String SQL_JOBS_BY_DATE ={CALL GetJobsWithCountByDate(?,?)};

private static Connection conn = ConnectionManager.getInstance()。getConnection();

public static void main(String [] args)throws异常{

EventQueue.invokeLater(new Runnable(){
public void run(){
try {
ProductionWindow frame = new ProductionWindow();
frame.setVisible(true);
} catch(Exception e){
e.printStackTrace();
}
}
});

ConnectionManager.getInstance()。setDBType(DBType.MYSQL);

JobManager.displayAllRows();

LocalDate searchDate = new LocalDate(2014,01,02);
日期sqlDate = Date.valueOf(searchDate.toString());

ResultSet rs = null;
try(
//创建一个语句对象(定义如何处理结果集)
CallableStatement stmt = conn.prepareCall(
SQL_JOBS_BY_DATE,
ResultSet。 TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
){
//为今天创建结果集。
stmt.setDate(1,sqlDate);
stmt.registerOutParameter(total,Types.INTEGER);
rs = stmt.executeQuery();

int nRows = stmt.getInt(total);

ShowJobs.displayData(rs,nRows);

ShowJobs.getTodaysJobs(rs,nRows,ProductionWindow,textField);

} catch(SQLException e){
//如果数据库有一些错误。
ConnectionManager.processException(e);
} finally {
rs.close();
}

ConnectionManager.getInstance()。close();

}

}

开发中;甚至没有测试过。我的问题是从Main类访问ProductionWindow的方法。在输入 ProductionWindow之后按[CTRL] - [SPACE],Eclipse不允许我选择 getTreeTable()方法。在Main附近的 ShowJobs.getTodaysJobs 行。



我知道这是一个明显的答案,一个很好的理由等,以及解决方案,使其在Java中更加正确。我只是不知道这一点,因为我还是Java和OOP的新手。

解决方案

根据这个问题和你的其他人,你似乎有一个具体的想法,这些窗口必须非常简单,没有其中的代码,然后被其他类外部操纵。这不是什么Swing(甚至是Java)。



想想JFrames和JDialogs作为你房子里的房间。你不会用你所有的正确的器具设置你的厨房,然后进入餐厅,并尝试远程工作炉子!



如果一个窗口的工作是填充屏幕中的一个表格,更新表格并处理与表格相关的用户输入,那么所有这些代码应该是窗口的类(不管是JFrame还是JDialog)。



想想焦点。如果用户的焦点和输入是在一个窗口内,那么处理该代码的代码也应该在该窗口内。



这是最基本的OOP原则之一: 封装


Really, really stupid question here. I'm new to Java (and OOP), coming from a Javascript (Extendscript, actually) background. I have a JFrame here:

package info.chrismcgee.sky.production;

import java.awt.EventQueue;
import java.awt.Font;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;

import net.miginfocom.swing.MigLayout;

import org.jdesktop.swingx.JXTreeTable;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;

public class ProductionWindow extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = -1899673458785493250L;
    private JPanel contentPane;
    private JTextField textField;
    private JLabel lblTodaysDate;
    private JXTreeTable treeTable;

    /**
     * Create the frame.
     */
    public ProductionWindow() {
        setMinimumSize(new Dimension(450, 300));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(new MigLayout("", "[][grow,center][]", "[][grow][]"));

        JButton btnPrev = new JButton("<- PREV");
        contentPane.add(btnPrev, "cell 0 0,alignx left");

        lblTodaysDate = new JLabel("Today's Date");
        lblTodaysDate.setHorizontalAlignment(SwingConstants.CENTER);
        lblTodaysDate.setFont(new Font("Lucida Grande", Font.PLAIN, 20));
        contentPane.add(lblTodaysDate, "cell 1 0,growx");

        JButton btnNext = new JButton("NEXT ->");
        contentPane.add(btnNext, "cell 2 0,alignx right");

        treeTable = new JXTreeTable();
        treeTable.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
        contentPane.add(treeTable, "cell 0 1 3 1,grow");

        JLabel lblTotal = new JLabel("Total:");
        lblTotal.setFont(new Font("Lucida Grande", Font.PLAIN, 24));
        contentPane.add(lblTotal, "cell 0 2");

        textField = new JTextField();
        textField.setEditable(false);
        textField.setHorizontalAlignment(SwingConstants.RIGHT);
        textField.setFont(new Font("Lucida Grande", Font.PLAIN, 24));
        textField.setText("1,000");
        contentPane.add(textField, "cell 1 2 2 1,growx");
        textField.setColumns(10);
    }

    public JPanel getContentPane() {
        return contentPane;
    }

    public void setContentPane(JPanel contentPane) {
        this.contentPane = contentPane;
    }

    public JTextField getTextField() {
        return textField;
    }

    public void setTextField(JTextField textField) {
        this.textField = textField;
    }

    public JLabel getLblTodaysDate() {
        return lblTodaysDate;
    }

    public void setLblTodaysDate(String today) {
        this.lblTodaysDate.setText(today);
    }

    public JXTreeTable getTreeTable() {
        return treeTable;
    }
}

I then call this code from a Main class:

package info.chrismcgee.sky.production;

import info.chrismcgee.sky.production.tables.JobManager;
import info.chrismcgee.sky.production.tables.ShowJobs;
import info.chrismcgee.util.InputHelper;

import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.apache.commons.io.FileUtils;
import org.joda.time.LocalDate;

public class Main {

    // This enum will call a stored procedure which returns all of a certain day's jobs.
    public static final String SQL_JOBS_BY_DATE = "{CALL GetJobsWithCountByDate(?, ?)}";

    private static Connection conn = ConnectionManager.getInstance().getConnection();

    public static void main(String[] args) throws Exception {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ProductionWindow frame = new ProductionWindow();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        ConnectionManager.getInstance().setDBType(DBType.MYSQL);

        JobManager.displayAllRows();

        LocalDate searchDate = new LocalDate(2014, 01, 02);
        Date sqlDate = Date.valueOf(searchDate.toString());

        ResultSet rs = null;
        try (
                // Create a statement object. (Defines how the result set is handled.)
                CallableStatement stmt = conn.prepareCall(
                        SQL_JOBS_BY_DATE,
                        ResultSet.TYPE_FORWARD_ONLY,
                        ResultSet.CONCUR_READ_ONLY);
                ) {
            // Create the result set for today.
            stmt.setDate(1, sqlDate);
            stmt.registerOutParameter("total", Types.INTEGER);
            rs = stmt.executeQuery();

            int nRows = stmt.getInt("total");

            ShowJobs.displayData(rs, nRows);

            ShowJobs.getTodaysJobs(rs, nRows, ProductionWindow, textField);

        } catch (SQLException e) {
            // In case there is some error with the database.
            ConnectionManager.processException(e);
        } finally {
            rs.close();
        }

        ConnectionManager.getInstance().close();

    }

}

This is still in development; haven't even tested it yet. My problem is accessing ProductionWindow's methods from the Main class. Eclipse doesn't let me choose the getTreeTable() method when I press [CTRL]-[SPACE] after typing ProductionWindow. in that ShowJobs.getTodaysJobs line near the end of Main.

I know there's an obvious answer for this, a good reason, etc., as well as solution to make it work that is more "proper" in Java. I just don't know any of this because I'm still new to Java and OOP.

解决方案

Judging by this question and some of your others, you seem to have a specific idea about these windows having to be very simple with no code in them, which then get manipulated externally by other classes. This is not what Swing (or even Java) is about.

Think of the JFrames and JDialogs as rooms in your house. You wouldn't set up your kitchen with all the right utensils and then go into the dining room and try to work the stove remotely!

If a window's job is to populate a table in the screen, update the table and deal with user input related to the table, then all of that code should be inside the Window's class (whether its a JFrame or a JDialog).

Think about focus. If the user's focus and input is inside a Window, then the code to deal with that should also be inside that Window.

This is one of the most fundamental OOP principles: Encapsulation

这篇关于从外部访问JFrame内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆