简体   繁体   English

如何构建Swing应用程序

[英]How To Structure a Swing Application

I don't really have much experience with swing, or GUI design in general for that matter (a few WPF applications in university is about the height of it), however I have been tasked with refactoring part of a swing legacy application at work. 我对摇摆或GUI设计一般没有多少经验(大学里的一些WPF应用程序的高度很高),但是我的任务是在工作中重构部分循环遗留应用程序。

The part I've been asked to refactor revolves around a popup window which can display in three different formats depending on a certain value object. 我被要求重构的部分围绕一个弹出窗口,该窗口可以根据特定的值对象以三种不同的格式显示。 These 3 different formats all share a few base fields, and then have additional ones determined conditionally. 这3种不同的格式都共享一些基本字段,然后有条件地确定其他格式。 The class responsible for this GUI element is ~5k long and I was thinking it should be split into three subclasses, with the shared stuff in base class which they all extend. 负责这个GUI元素的类长约5k,我认为它应该分成三个子类,基类中的共享内容都可以扩展。 However I have absolutely no idea if this is the correct approach or not. 但是我绝对不知道这是否是正确的方法。

Could anyone highlight some strategies used in dealing with different swing components which share elements such as buttons/fields etc? 任何人都可以强调一些用于处理不同摆动组件的策略,这些组件共享按钮/字段等元素吗?

Additionally, are there any large OSS swing applications which can be used to learn from? 此外,是否有任何大型OSS摇摆应用程序可用于学习?

More info: The application I am working on is a large legacy application which is rather horrifically structured at the moment. 更多信息:我正在处理的应用程序是一个庞大的遗留应用程序,目前相当可怕的结构。 I'm new to the team (and a fairly recent grad so don't have much experience in this area) and have been asked to try and break down one of the huge classes which is responsible for the display of this popup at the moment into smaller more maintainable components. 我是团队的新手(也是一个相当近的毕业生,因此在这个领域没有太多的经验)并且被要求尝试分解一个负责显示此弹出窗口的巨大课程更小的可维护组件。 Essentially there is a pop up in the application which allows the user to respond to certain events, and this has three different appearances depending on the sub type of the request they need to respond to. 实际上,应用程序中有一个弹出窗口允许用户响应某些事件,这有三种不同的外观,具体取决于他们需要响应的请求的子类型。 A large portion of the GUI elements are consistent across all three sub types, as such I am interested to know if inheritance would be the best approach here or are there other strategies for dealing with this? 很大一部分GUI元素在所有三种子类型中是一致的,因此我很想知道继承是否是这里最好的方法还是有其他策略来处理这个?

Reading the comments, I think I can answer this question. 阅读评论,我想我可以回答这个问题。 A true answer would require a book. 一个真正的答案需要一本书。

  1. Break up your GUI into as many nested JPanel s as it takes to describe your GUI. 将GUI分解为尽可能多的嵌套JPanel ,以描述GUI。 A simple nested JPanel that uses a BorderLayout is preferable to a complicated JPanel that uses a GridBagLayout . 使用BorderLayout简单嵌套JPanel比使用GridBagLayout的复杂JPanel更可取。 To be clear, I'm not criticizing a GridBagLayout . 要清楚,我不批评GridBagLayout It's useful when creating a form. 它在创建表单时很有用。 But it's not the only Swing layout manager. 但它不是唯一的Swing布局管理器。

  2. Put each nested JPanel into its own class. 将每个嵌套的JPanel放入自己的类中。

  3. Use composition when using Swing components. 使用Swing组件时使用组合。 Use inheritance if and only if your class will override one of the JComponent methods. 当且仅当您的类将覆盖其中一个JComponent方法时才使用继承。

  4. Each JPanel has its own JButton , JLabel , etc. components. 每个JPanel都有自己的JButtonJLabel等组件。 JBUtton A is defined for JPanel A, and JButton B is defined for JPanel B, even if the user of the GUI thinks they are the same button. JBUtton A是为JPanel A定义的,而JButton B是为JPanel B定义的,即使GUI的用户认为它们是相同的按钮。 You can minimize the duplication by creating a GUI model that contains the text of the labels and buttons. 您可以通过创建包含标签和按钮文本的GUI模型来最小化重复。 You must eliminate the duplication of action code (the code that's executed when the button is pressed) by writing common ActionListener s that JButton A and JButton B can execute. 您必须通过编写JButton A和JButton B可以执行的公共ActionListener来消除动作代码的重复(按下按钮时执行的代码)。

  5. A Swing application must start with a call to SwingUtilities.invokelater() . Swing应用程序必须以调用SwingUtilities.invokelater() This ensures that the Swing components are defined and used on the Event Dispatch thread (EDT). 这可确保在Event Dispatch线程(EDT)上定义和使用Swing组件。

  6. Only one JFrame is used in a Swing application. 在Swing应用程序中只使用一个 JFrame

  7. Each JPanel must have a Swing layout manager defined. 每个JPanel 必须定义一个Swing布局管理器。

  8. Certain components, like JList and JTable , work better when enclosed in a JScrollPane . 某些组件(如JListJTable在封装在JScrollPane时效果更好。

I'm sure I've forgotten a few things, but this should be a good start. 我敢肯定我已经忘记了一些事情,但这应该是一个好的开始。

What if you were to set up an abstract class that creates the 50% shared code, and then extend from that? 如果您要设置一个创建50%共享代码的抽象类,然后从中扩展,该怎么办?

For example: 例如:

abstract class BasePopupPanel extends JPanel {

    public void initialize() {
        // Initialize all the shared code here.
        // eg. add(new JButton("TEST");
    }
}

And now you create the actual popup panels: 现在您创建实际的弹出面板:

public class GiraffePopupPanel extends BasePopupPanel {

    public void initialize() {
        super.initialize();
        // Here you do all the initializations for this class.
    }
}

You can create as many of these as you would like. 您可以根据需要创建尽可能多的这些内容。 When it comes time to add them... 什么时候添加它们...

...let's say you have a method that is called displayPopup , then the signature would look like this: ...假设您有一个名为displayPopup的方法,那么签名将如下所示:

public void displayPopup(BasePopupPanel popup) {
    // do stuff regarding JDialogs, etc.
    // ...
    popup.initialize();
    // do more stuff...
}

I hope that gives you one view on how you could refactor your classes. 我希望能给你一个关于如何重构课程的观点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM