【问题标题】:Hand-coded GUI - Java [closed]手工编码的 GUI - Java [关闭]
【发布时间】:2012-04-23 00:39:14
【问题描述】:

我正在尝试使用 Swing 和 AWT 手动编写 Java GUI。我正在使用各种布局来尝试实现或类似于下面发布的 GUI(这是用 Pencil 制作的模拟布局):

到目前为止,我得到的就是这个,但似乎无法让它更“礼貌”、更具吸引力和用户友好。

这是我到目前为止所做的代码:

import java.awt.*; 
import javax.swing.*;
import javax.swing.JTable;


public class GUI extends JFrame {

    public void buildGui() {

        JFrame frame = new JFrame("Hotel TV Scheduler");

                JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout(0,0));

                JPanel chPanel = new JPanel();
                chPanel.setLayout(new GridLayout(3,2));

                JPanel listPanel = new JPanel();
                listPanel.setLayout(new GridLayout(3,2));

                JPanel infoPanel = new JPanel();
        infoPanel.setLayout(new GridLayout(0,2));


                JPanel addPanel = new JPanel();
        addPanel.setLayout(new GridLayout(0,3));


                mainPanel.add(chPanel, BorderLayout.LINE_START);
                mainPanel.add(listPanel, BorderLayout.CENTER);
                mainPanel.add(infoPanel, BorderLayout.LINE_END);


                JTable chOneTable = new JTable();
                JTable chTwoTable = new JTable();
                JTable listTable = new JTable();

                JLabel ch1Label = new JLabel("Channel 1");
                JLabel ch2Label = new JLabel("Channel 2");
                JLabel listLabel = new JLabel("List");

                JButton rmvChOneButton = new JButton("Remove Channel");
                JButton rmvChTwoButton = new JButton("Remove Channel");

                chPanel.add(ch1Label);
                chPanel.add(ch2Label);
                chPanel.add(chOneTable);
                 chPanel.add(chTwoTable);
                chPanel.add(rmvChOneButton);                                         
                chPanel.add(rmvChTwoButton);

                listPanel.add(listLabel);
                listPanel.add(listTable);                



                JLabel titleLabel = new JLabel("Title");
                JLabel genreLabel = new JLabel("Genre");
                JLabel durationLabel = new JLabel("Duration");
                JLabel actorLabel = new JLabel("Actor");
                JLabel directorLabel = new JLabel("Director");
                JLabel rentableLabel = new JLabel("Rentable");
                JLabel synLabel = new JLabel("Synopsis");

                JTextField txtTitle = new JTextField();          
                JTextField txtGenre = new JTextField();
                JTextField txtDuration = new JTextField();
                JTextField txtActor = new JTextField();
                JTextField txtDirector = new JTextField();
                JTextField txtSynopsis = new JTextField();

                JCheckBox rentCB = new JCheckBox();

                JButton btnAddProg = new JButton("Add Program");

                JList channelList = new JList();
                JList timeList = new JList();

                infoPanel.add(titleLabel);
                infoPanel.add(txtTitle);
                infoPanel.add(genreLabel);
                infoPanel.add(txtGenre);
                infoPanel.add(durationLabel);
                infoPanel.add(txtDuration);
                infoPanel.add(actorLabel);
                infoPanel.add(txtActor);
                infoPanel.add(directorLabel);
                infoPanel.add(txtDirector);
                infoPanel.add(rentableLabel);
                infoPanel.add(rentCB);
                infoPanel.add(synLabel);
                infoPanel.add(txtSynopsis);
                infoPanel.add(btnAddProg);
                infoPanel.add(channelList);
                infoPanel.add(timeList);


                frame.add(mainPanel);
                frame.setVisible(true);


    }


}

它不必与上面显示的模拟布局完全相同,但尽可能相似或至少更用户友好。

我想使用除 GridBagLayout 和 SwingLayout 之外的任何东西。

关于如何改进代码并使其看起来更相似的任何想法?

感谢任何帮助。

布赖恩

【问题讨论】:

  • 学习 GridBagLayout。它真的会帮助这里的事情。我知道这很困难,但要咬紧牙关。
  • 实际上这是一个学校作业,我们被要求不要使用它,原因很简单,您可以找到使用 GridBagLayout 的 GUI 创建者。
  • 叹息...我的建议是尽可能多地嵌套布局以获得所需的结果。
  • 祝你好运。如果它应该是可调整大小的,那么这将是非常困难的。如果没有,那么您可以尝试使用JPanelsFlowLayout 完全构建它,这样您就可以告诉组件它们应该有多大。当然,您根本不必使用任何 LayoutManager。您可以使用setBounds() 安排每一件作品,但这并不好玩。我现在没有时间,但也许我稍后会用 FlowLayouts 做点什么。

标签: java swing user-interface layout awt


【解决方案1】:

看看MigLayout。它的许可非常具有包容性:

MigLayout 可免费用于商业和非商业项目,并提供源代码。它是在非常免费的 BSD 或 GPL 许可下获得许可的,无论您喜欢哪种方式

JNLP demo application 应该显示很好的示例和相应的来源。

另外,尽量避免嵌套逻辑上不相关的组件。随着嵌套程度的增加,对齐、边框和填充变得非常痛苦。

【讨论】:

    【解决方案2】:

    GUI 最需要的是:

    • 组件之间的空白。两种常见的提供方法是:
      1. 布局构造函数中提供的布局填充。
      2. 向组件或容器添加EmptyBorder。对于很多组件已经有边框的情况,最好用JPanel包裹起来,给面板加上边框。
    • 约束面板。例如。如果希望在BorderLayoutWEST 中有一组组件被“推到顶部”,请将它们添加到另一个具有BorderLayout.NORTH 布局/约束的面板中。这是an example 我的意思。

    【讨论】:

    • @mKorbel 我仍然想知道所有 “真正的 LayoutManager 大师” 都藏在哪里。 ;)
    【解决方案3】:

    使用 Eclipse 和 WindowBuilder。您可以稍后返回并“手动编码”特定部分,如果您愿意,仍然可以返回到 WindowBuilder。

    【讨论】:

    • Netbeans 曾经有一个非常不错的 GUI 构建器(不确定它是否还有)。 Intellij IDEA 也有一个,但我认为它只适用于付费版本。
    【解决方案4】:

    看看这个示例程序,它会满足你的需求吗:-)

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.TitledBorder;
    import javax.swing.table.DefaultTableModel;
    
    public class TVSchedule
    {
        private static final int GAP = 5;
        private static TVSchedule tvSchedule;
    
        private void createAndDisplayGUI()
        {
            JFrame frame = new JFrame("HOTEL TV SCHEDULE");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.setLocationByPlatform(true);
    
            JPanel contentPane = new JPanel();
            contentPane.setLayout(new BorderLayout());
    
            JPanel centerPanel = new JPanel();
            //centerPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
            centerPanel.setLayout(new GridLayout(0, 4, 5, 5));
            centerPanel.add(createChannelOnePanel());
            centerPanel.add(createChannelTwoPanel());
            centerPanel.add(createListPanel());
            centerPanel.add(createInformationPanel());
    
            JPanel bottomPanel = new JPanel();
            bottomPanel.setOpaque(true);
            bottomPanel.setBackground(Color.RED.darker());
            bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
            JButton exitButton = new JButton("EXIT");
            bottomPanel.add(exitButton);
    
            contentPane.add(centerPanel, BorderLayout.CENTER);
            contentPane.add(bottomPanel, BorderLayout.PAGE_END);
    
            frame.setContentPane(contentPane);
            frame.pack();
            frame.setVisible(true);
        }
    
        private JPanel createChannelOnePanel()
        {
            JPanel panel = new JPanel();
            panel.setLayout(new GridBagLayout());
            panel.setOpaque(true);
            panel.setBackground(Color.DARK_GRAY);
            panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
            GridBagConstraints gbc = new GridBagConstraints();
    
            String[] columnNames = {
                                        "Time",
                                        "Title"
                                   }; 
            Object[][] data = {
                                {"01:00","Cowboy and Alchemist."}
                              };
            DefaultTableModel model = new DefaultTableModel(data, columnNames);
            JTable table = new JTable( model )
            {
                //  Returning the Class of each column will allow different
                //  renderers to be used based on Class
                public Class getColumnClass(int column)
                {
                    return getValueAt(0, column).getClass();
                }
            };                      
    
            table.setPreferredScrollableViewportSize(new Dimension(200, 200));
            table.setFillsViewportHeight(true);
            JScrollPane scrollPane = new JScrollPane(table);
            scrollPane.setBorder(BorderFactory.createTitledBorder(
                            BorderFactory.createLineBorder(Color.BLACK, 1)
                            , "Channel 1"
                            , TitledBorder.CENTER
                            , TitledBorder.DEFAULT_POSITION));      
            gbc.weightx = 1.0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridwidth = 2;
            panel.add(scrollPane, gbc);     
    
            JButton removeButton = new JButton("Remove Selected");
            gbc.weightx = 1.0;
            gbc.gridx = 0;
            gbc.gridy = 3;
            gbc.gridwidth = 2;
            panel.add(removeButton, gbc);
    
            return panel;
        }
    
        private JPanel createChannelTwoPanel()
        {
            JPanel panel = new JPanel();
            panel.setLayout(new GridBagLayout());
            panel.setOpaque(true);
            panel.setBackground(Color.WHITE);
            panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
            GridBagConstraints gbc = new GridBagConstraints();
    
            String[] columnNames = {
                                        "Time",
                                        "Title"
                                   }; 
            Object[][] data = {
                                {"02:00","Grey's Anatomy"}
                              };
            DefaultTableModel model = new DefaultTableModel(data, columnNames);
            JTable table = new JTable( model )
            {
                //  Returning the Class of each column will allow different
                //  renderers to be used based on Class
                public Class getColumnClass(int column)
                {
                    return getValueAt(0, column).getClass();
                }
            };                      
    
            table.setPreferredScrollableViewportSize(new Dimension(200, 200));
            table.setFillsViewportHeight(true);
            JScrollPane scrollPane = new JScrollPane(table);
            scrollPane.setBorder(BorderFactory.createTitledBorder(
                            BorderFactory.createLineBorder(Color.BLACK, 1)
                            , "Channel 2"
                            , TitledBorder.CENTER
                            , TitledBorder.DEFAULT_POSITION));      
            gbc.weightx = 1.0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridwidth = 2;
            panel.add(scrollPane, gbc);     
    
            JButton removeButton = new JButton("Remove Selected");
            gbc.weightx = 1.0;
            gbc.gridx = 0;
            gbc.gridy = 3;
            gbc.gridwidth = 2;
            panel.add(removeButton, gbc);
    
            return panel;
        }
    
        private JPanel createListPanel()
        {       
            JPanel panel = new JPanel();
            panel.setLayout(new GridBagLayout());
            panel.setOpaque(true);
            panel.setBackground(Color.DARK_GRAY);
            panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
            GridBagConstraints gbc = new GridBagConstraints();
    
            String[] columnNames = {
                                        "Genre",
                                        "Title",
                                        "Duration (Hours)"
                                   }; 
            Object[][] data = {
                                {"Comedy","C & A", "1.5"}
                              };
            DefaultTableModel model = new DefaultTableModel(data, columnNames);
            JTable table = new JTable( model )
            {
                //  Returning the Class of each column will allow different
                //  renderers to be used based on Class
                public Class getColumnClass(int column)
                {
                    return getValueAt(0, column).getClass();
                }
            };                      
    
            table.setPreferredScrollableViewportSize(new Dimension(200, 200));
            table.setFillsViewportHeight(true);
            JScrollPane scrollPane = new JScrollPane(table);
            scrollPane.setBorder(BorderFactory.createTitledBorder(
                            BorderFactory.createLineBorder(Color.BLACK, 1)
                            , "List"
                            , TitledBorder.CENTER
                            , TitledBorder.DEFAULT_POSITION));
            gbc.weightx = 1.0;
            gbc.anchor = GridBagConstraints.PAGE_START;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridwidth = 2;
            panel.add(scrollPane, gbc); 
    
            gbc.weightx = 1.0;
            gbc.gridx = 0;
            gbc.gridy = 3;
            gbc.gridwidth = 2;
            panel.add(Box.createRigidArea(new Dimension(100, 30)), gbc);    
    
            return panel;
        }
    
        private JPanel createInformationPanel()
        {
            JPanel bottomPanel = new JPanel();
            bottomPanel.setLayout(new GridLayout(0, 1, 2, 2));
            bottomPanel.setBorder(BorderFactory.createTitledBorder(
                            BorderFactory.createLineBorder(Color.BLACK, 1)
                            , "Information"
                            , TitledBorder.LEFT
                            , TitledBorder.DEFAULT_POSITION));
    
            JPanel panel = new JPanel();
            panel.setOpaque(true);
            panel.setBackground(Color.WHITE);
            panel.setLayout(new GridBagLayout());
            panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
            GridBagConstraints gbc = new GridBagConstraints();
    
            JLabel titleLabel = new JLabel("TITLE : ");
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridx = 0;
            gbc.gridy = 0;
            panel.add(titleLabel, gbc);
    
            JTextField titleField = new JTextField(10);
            gbc.gridx = 1;
            panel.add(titleField, gbc);
    
            JLabel genreLabel = new JLabel("GENRE : ");
            gbc.gridx = 0;
            gbc.gridy = 1;
            panel.add(genreLabel, gbc);
    
            JTextField genreField = new JTextField(10);
            gbc.gridx = 1;
            panel.add(genreField, gbc);
    
            JLabel durationLabel = new JLabel("DURATION : ");
            gbc.gridx = 0;
            gbc.gridy = 2;
            panel.add(durationLabel, gbc);
    
            JTextField durationField = new JTextField(10);
            gbc.gridx = 1;
            panel.add(durationField, gbc);
    
            JLabel actorLabel = new JLabel("ACTOR : ");
            gbc.gridx = 0;
            gbc.gridy = 3;
            panel.add(actorLabel, gbc);
    
            JTextField actorField = new JTextField(10);
            gbc.gridx = 1;
            panel.add(actorField, gbc);
    
            JLabel directorLabel = new JLabel("DIRECTOR : ");
            gbc.gridx = 0;
            gbc.gridy = 4;
            panel.add(directorLabel, gbc);
    
            JTextField directorField = new JTextField(10);
            gbc.gridx = 1;
            panel.add(directorField, gbc);
    
            JLabel rentLabel = new JLabel("RENTABLE : ");
            gbc.gridx = 0;
            gbc.gridy = 5;
            panel.add(rentLabel, gbc);
    
            JCheckBox rentCBox = new JCheckBox(" ", false);
            rentCBox.setOpaque(true);
            rentCBox.setBackground(Color.WHITE);
            rentCBox.setHorizontalTextPosition(SwingConstants.LEFT);
            gbc.gridx = 1;
            panel.add(rentCBox, gbc);
    
            JLabel synopsisLabel = new JLabel("SYNOPSIS : ");
            gbc.gridx = 0;
            gbc.gridy = 6;
            panel.add(synopsisLabel, gbc);
    
            JTextArea synopsisArea = new JTextArea(10, 5);
            synopsisArea.setBackground(Color.BLUE.darker());
            synopsisArea.setForeground(Color.WHITE);
            synopsisArea.setCaretColor(Color.WHITE);
            gbc.gridx = 1;
            gbc.gridwidth = 2;
            gbc.gridheight = 2;
            panel.add(synopsisArea, gbc);
    
            JButton addProgramButton = new JButton("Add Program");
            gbc.gridx = 0;
            gbc.gridy = 8;
            gbc.insets = new Insets(5, 5, 5, 5);
            gbc.anchor = GridBagConstraints.PAGE_END;
            gbc.gridwidth = 1;
            gbc.gridheight = 1;
            panel.add(addProgramButton, gbc);
    
            JSpinner spinner = new JSpinner(new SpinnerNumberModel(00.15, 00.15, 60.00, 00.15));
            gbc.gridx = 2;
            gbc.gridy = 8;      
            panel.add(spinner, gbc);
    
            bottomPanel.add(panel);
            return bottomPanel;
        }
    
        public static void main(String... args)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    tvSchedule = new TVSchedule();
                    tvSchedule.createAndDisplayGUI();
                }
            });
        }
    }
    

    我真的不知道你在 JButton 和 'JSpinner' 之间使用了什么,这就是为什么从来没有在那里添加任何东西,希望你可以自己做。

    这是相同的输出:

    【讨论】:

    • @mKorbel : 呵呵,谢谢 :-)
    猜你喜欢
    • 2010-09-28
    • 2010-10-02
    • 1970-01-01
    • 2010-09-10
    • 2017-03-21
    • 2012-05-04
    • 2013-04-18
    • 2012-09-26
    • 2012-09-29
    相关资源
    最近更新 更多