Java 使用来自一个源的两个GUI

Java 使用来自一个源的两个GUI,java,swing,user-interface,code-duplication,Java,Swing,User Interface,Code Duplication,我正在处理一个现有的项目,我想简化它,使之可用。我有两个GUI,我希望他们只从一个资源获取它们的GUI代码。我的意思是有gui1.java和gui2.java由它们的GUI代码组成。还有一个是它们的共同部分。让我们称之为common.java。使用gui选择部分,我可以满足所选择的gui(gui 1或gui 2)。我想通过JFrame扩展common.java,然后用common.java扩展gui1.java和gui2.java。此外,如果其中一个gui存在外部部分,我可以使用If条件添加外部

我正在处理一个现有的项目,我想简化它,使之可用。我有两个GUI,我希望他们只从一个资源获取它们的GUI代码。我的意思是有
gui1.java
gui2.java
由它们的GUI代码组成。还有一个是它们的共同部分。让我们称之为
common.java
。使用gui选择部分,我可以满足所选择的gui(gui 1或gui 2)。我想通过
JFrame
扩展
common.java
,然后用
common.java
扩展
gui1.java
gui2.java
。此外,如果其中一个gui存在外部部分,我可以使用If条件添加外部部分(正如我所说,我可以确定选择了哪个gui)。例如:

protected void MovementStateControl() {
        try {
            URL url = new URL(NameofMyproject.GetWepIp() + "<MESSAGE><Command_No>4</Command_No></MESSAGE>");
            URLConnection connection = url.openConnection();
            Document doc = parseXML(connection.getInputStream());
            NodeList Settings = doc.getElementsByTagName("SYSTEM_SETTINGS");
            Node MovementSystem = Settings.item(0);
            Element MovementElem = (Element) MovementSystem;
            jLabel7.setText(MovementElem.getElementsByTagName("device_name").item(0).getTextContent());
            SystemGuiSelect.DeviceName = MovementElem.getElementsByTagName("device_name").item(0).getTextContent();
            NameofMyproject.signal_max_level = Integer.parseInt(MovementElem.getElementsByTagName("signal_max_val").item(0).getTextContent());

            /* If gui1 is selected, the part should be done as well. Otherwise, just above part okay. */
            if (gui1) {
                NameofMyproject.signal_min_level = Integer.parseInt(MovementElem.getElementsByTagName("signal_min_val").item(0).getTextContent());
                if (!"EXISTS".equals(MovementElem.getElementsByTagName("polarization_system").item(0).getTextContent())) {
                    jLabel24.setVisible(false);
                    LblPolAngle.setVisible(false);
                    lblPolTarget.setVisible(false);
                    jLabel13.setVisible(false);
                    jTextField3.setVisible(false);
                    jButton16.setVisible(false);
                    jButton8.setText("Tx-Xy");
                    jButton3.setVisible(false);
                    jButton4.setVisible(false);
                    jProgressBar3.setVisible(false);
                    jLabel36.setVisible(false);
                    jLabel37.setVisible(false);
                    jLabel5.setVisible(false);
                    jButton18.setVisible(false);
                } else {
                    jLabel24.setVisible(true);
                    LblPolAngle.setVisible(true);
                    lblPolTarget.setVisible(true);
                    jLabel13.setVisible(true);
                    jTextField3.setVisible(true);
                    jButton16.setVisible(true);
                    jButton8.setText("Tx-Xy-Zu");
                    jButton3.setVisible(true);
                    jButton4.setVisible(true);
                    jProgressBar3.setVisible(true);
                    jLabel36.setVisible(true);
                    jLabel37.setVisible(true);
                    jLabel5.setVisible(true);
                    jButton18.setVisible(true);
                }
            }

        } catch (Exception e) {  }
    }
受保护的void MovementStateControl(){
试一试{
URL=新URL(NameofMyproject.GetWepIp()+“4”);
URLConnection=url.openConnection();
Document doc=parseXML(connection.getInputStream());
节点列表设置=doc.getElementsByTagName(“系统设置”);
节点移动系统=设置。项(0);
元素MovementElem=(元素)MovementSystem;
jLabel7.setText(MovementElem.getElementsByTagName(“设备名称”).item(0.getTextContent());
SystemGuiSelect.DeviceName=MovementElem.getElementsByTagName(“设备名称”).item(0.getTextContent();
NameofMyproject.signal_max_level=Integer.parseInt(MovementElem.getElementsByTagName(“signal_max_val”).item(0.getTextContent());
/*如果选择了gui1,那么该部分也应该完成。否则,仅在该部分上方即可*/
if(gui1){
NameofMyproject.signal\u min\u level=Integer.parseInt(MovementElem.getElementsByTagName(“signal\u min\u val”).item(0.getTextContent());
if(!“EXISTS”.equals(MovementElem.getElementsByTagName(“极化系统”).item(0.getTextContent()){
jLabel24.setVisible(假);
LblPolAngle.setVisible(false);
lblpoltaget.setVisible(false);
jLabel13.setVisible(false);
jTextField3.setVisible(false);
jButton16.setVisible(false);
jButton8.setText(“Tx Xy”);
jButton3.setVisible(false);
jButton4.setVisible(false);
jProgressBar3.setVisible(false);
jLabel36.setVisible(假);
jLabel37.setVisible(假);
jLabel5.setVisible(假);
jButton18.setVisible(假);
}否则{
jLabel24.setVisible(true);
LblPolAngle.setVisible(true);
lblpoltaget.setVisible(true);
jLabel13.setVisible(true);
jTextField3.setVisible(true);
jButton16.setVisible(true);
jButton8.setText(“Tx Xy Zu”);
jButton3.setVisible(true);
jButton4.setVisible(true);
jProgressBar3.setVisible(true);
jLabel36.setVisible(true);
jLabel37.setVisible(true);
jLabel5.setVisible(真);
jButton18.setVisible(true);
}
}
}捕获(例外e){}
}

问题在于,我希望将通用GUI部件放入
common.java
中,以消除代码重复,因为两个GUI相同的代码太多了。当然,因为
common.java
是一个超类,所以它不能意识到其子类的元素。(jlabel、JButtons等无法识别)即使它们的
线程
部分是相同的,我也无法从同一个源向它们提供信息。GUI是使用NetBeans创建的。顺便说一句,我对这个问题的解决方案是在所有方法中添加参数,但是对于这个方法,有多少个参数呢?(可能我使用VARG)但是,我想知道是否有更有效的解决方案。

基于您的方法示例,我建议您使用简单的解决方案来解决您的问题。
首先,正如Gilbert所建议的,公共窗口小部件(textfield、label等)必须在抽象的公共类中,如果可能的话,必须放在公共类中(更简单)。当然,具体gui的特定小部件将在具体类中。 为了简化由具体类操作的公共小部件的使用,请在抽象公共类中将字段声明为受保护

第二,在你的代码片段中,你做到了

 if (gui1) { then...
我建议您创建侦听器,而不是不需要(了解children guy不是父类的角色)和繁琐(当时不可维护)的条件语句。这些将是您的具体类必须实现的简单接口
当父类发送事件时,它只向具体类发送“动作”或“不动作”的责任。 为了强制具体类实现该接口,请使抽象类成为实现该接口的公共类。 这样,具体类就没有实现它的选择

下面是一个带有两个GUI的非常简单的示例,说明了所提出的概念:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public abstract class CommonFrame extends JFrame implements MyFrameListener {

    protected JLabel myLabelForControlMove;
    private JButton btnControlMove;
    private JPanel panel;

    public CommonFrame() {
        panel = new JPanel();
        add(panel);
        myLabelForControlMove = new JLabel("waiting for information...");
        panel.add(myLabelForControlMove);
        btnControlMove = new JButton("click to control move");
        panel.add(btnControlMove);
        setVisible(true);
        pack();


        // call concrete class with no aware which one is used
        onMovementStateCreation();

        btnControlMove.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
            // call concrete class with no aware which one is used
            onMovementStateControl();
            }
        });
    }
}



public interface MyFrameListener {

  void onMovementStateCreation();

  void onMovementStateControl();

}


public class Gui1 extends CommonFrame {

 @Override
 public void onMovementStateCreation() {
   myLabelForControlMove.setText("control starts");
 }

 @Override
 public void onMovementStateControl() {
   myLabelForControlMove.setText("control with state Gui1");
 }

}


public class Gui2 extends CommonFrame {

  @Override
  public void onMovementStateCreation() {
    myLabelForControlMove.setText("control with state Gui2");
  }

  @Override
  public void onMovementStateControl() {
    // does nothing
  }

}

正如您提到的,超类不应该知道它的子类。 不要使用继承,而是使用合成

java应该由它的专用容器组成。这将使common.java与gui1.java和gui2.java分离,将来如果您需要添加新的gui3.java,则不会破坏任何API,只需创建一个新的SpecializedGUI.java即可


据我所知,您需要处理两个基本问题。第一个是将UI视图与控制逻辑分离,第二个是增加用户界面中的重用