Java Swing JScrollPane显示的输出与本书显示的不同。行标签在Java中消失了

时间:2013-01-05 20:00:37

标签: java swing containers jscrollpane

以下代码没有给出它应该的输出。它应该给出的输出如下所示:

Output that I want to get

而不是那个输出,我得到一个输出,如下所示:

Wrong output that I get now

我注意到我没有得到的是:

  1. 我没有让ScrollBars垂直和水平。
  2. 我没有获得面板'p'中每一行的行标题。
  3. 这种格式似乎也很不安。当程序启动时,直到我将鼠标移到它们上方才能看到单选按钮。
  4. 此代码来自使用Eclipse IDE的Oracle Swing的O'REILLY书(第11章)。


    package khan.ajmal.oreilly.swing;
    
    import java.awt.Window;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    public class BasicWindowMonitor extends WindowAdapter {
    
        @Override
        public void windowClosing(WindowEvent e) {
            Window w = e.getWindow();
            w.setVisible(false);
            w.dispose();
            System.exit(0);
        }
    }
    

    / 一个组件大于应用程序窗口的JScrollPane。 / package khan.ajmal.oreilly.swing.Chapter11_SpecialtyPanesAndLayoutManagers;

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.ButtonGroup;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.JScrollPane;
    import javax.swing.JViewport;
    import javax.swing.ScrollPaneConstants;
    
    import khan.ajmal.oreilly.swing.BasicWindowMonitor;
    
    public class ScrollDemo2 extends JFrame {
        JScrollPane scrollPane = new JScrollPane();
    
    // Constructor
        public ScrollDemo2() {
            super("JScrollPane Demonstration");
    
        /* Add in some JViewports for the column and row headers */
            JViewport jv1 = new JViewport();
            jv1.setView(new JLabel(
                new ImageIcon(
                           "C:/Users/Ajmal/workspace/OreillySwing/src/khan/ajmal/oreilly/swing/Chapter11_SpecialtyPanesAndLayoutManagers/columnLabel.jpg")));
    
            scrollPane.setColumnHeader(jv1);
    
            JViewport jv2 = new JViewport();
            jv2.setView(new JLabel(
                new ImageIcon(
                        "C:/Users/Ajmal/workspace/OreillySwing/src/khan/ajmal/oreilly/swing/Chapter11_SpecialtyPanesAndLayoutManagers/rowLabel.jpg")));
        scrollPane.setRowHeader(jv2);
    
        /* And throw in an information button */
        JButton jb1 = new JButton(
                new ImageIcon(
                        "C:/Users/Ajmal/workspace/OreillySwing/src/khan/ajmal/oreilly/swing/Chapter11_SpecialtyPanesAndLayoutManagers/question.jpg"));
        jb1.addActionListener(new ActionListener() {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                String message = "This is an active corner!";
                String title = "Information";
                int type = JOptionPane.INFORMATION_MESSAGE;
                JOptionPane.showMessageDialog(null, message, title, type);
            }// method actionPerformed ends here.
        }// Definition of inner class ActionListener ends here.
        );/* Passing arguments to method addActionListener ends here. */
        scrollPane.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, jb1);
        setSize(300, 200);
        addWindowListener(new BasicWindowMonitor());
        init();
        setVisible(true);
    }// Constructor ends here.
    
    private void init() {
        JRadioButton form[][] = new JRadioButton[12][5];
        String counts[] = { " ", "0-1", "2-5", "6-10", "11-100", "101+" };
        String categories[] = { "Household", "Office", "Extended Family",
                "Company (US)", "Company (World)", "Team", "Will",
                "Birthday Card List", "High School", "Country", "Continent",
                "Planet" };
        JPanel p = new JPanel();
        p.setSize(600, 400);
        p.setLayout(new GridLayout(13, 6, 10, 0));
    
        for (int row = 0; row < 13; row++) {
            // creating a button group in each iteration of the row loop
            ButtonGroup bg = new ButtonGroup();
            for (int col = 0; col < 6; col++) {
                // We need to create column headers in the first row
                if (row == 0)
                    p.add(new JLabel(counts[col]));
                else {
                    /*
                     * When the control moves to a new row, check for the
                     * column. In the first column put row headers
                     */
                    if (col == 0) {
                        p.add(new JLabel(categories[row - 1]));/*
                                                                 * row will have
                                                                 * at least
                                                                 * value of 1
                                                                 * when control
                                                                 * is at this
                                                                 * line.
                                                                 */
                    } else {
                        form[row - 1][col - 1] = new JRadioButton();
                        bg.add(form[row - 1][col - 1]);/*
                                                         * add this button to
                                                         * the button group
                                                         */
                        p.add(form[row - 1][col - 1]);
                    }
                }
            }// col for loop ends here.
        }// row for loop ends here.
    
        // Adding the panel to a scrollpane
        // scrollPane = new JScrollPane(p);
        scrollPane.add(p);
        // adding the scrollpane to the contentpane of the frame
        getContentPane().add(scrollPane, BorderLayout.CENTER);
    }// method init ends here.
    
    public static void main(String[] args) {
        new ScrollDemo2();
    }// method main ends here.
    
    }// class ScrollDemo2 ends here.
    

1 个答案:

答案 0 :(得分:0)

在代码中初始化组件的顺序存在一些问题。这些有点难以挑选,因此我冒昧地重新组织您的代码以使事情更加清晰。我想你会发现这个代码更可行。 (注意:我删除了BasicWindowAdapter的导入以及对ImageIcon的调用)

一些外卖提示:

  1. 尝试仅在一种方法中使用给定的组件。您的代码从构造函数和init()访问scrollPane。
  2. 不要犹豫,创建一些非常具体的方法,这些方法需要特定的输入,并提供特定的输出。例如,下面的createScrollPane()接受一个JPanel并返回一个JScrollPane。很清楚该方法的作用,并且不需要使用具有类范围的变量。
  3. 尽量不在构造函数中构建UI。一个好的做法是创建一个init()方法,并让init()调用其他方法来构建UI的特定部分。
  4. 以下是您修改过的代码:

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.ButtonGroup;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.JScrollPane;
    import javax.swing.JViewport;
    import javax.swing.ScrollPaneConstants;
    
    public class ScrollDemo2 extends JFrame {
    
    // Constructor
    public ScrollDemo2() {
        super("JScrollPane Demonstration");
        init();
        setSize(300, 200);
        setVisible(true);
    }// Constructor ends here.
    
    private void init() {
        JPanel panel = createFormPanel();
        JScrollPane scrollPane = createScrollPane(panel);
        this.getContentPane().add(scrollPane, BorderLayout.CENTER);
    }// method init ends here.
    
    
    private JPanel createFormPanel() {
        JRadioButton form[][] = new JRadioButton[12][5];
    
        JPanel p = new JPanel();
        p.setSize(600, 400);
        p.setLayout(new GridLayout(13, 6, 10, 0));
    
        for (int row = 0; row < 13; row++) {
            // creating a button group in each iteration of the row loop
            ButtonGroup bg = new ButtonGroup();
            for (int col = 0; col < 6; col++) {
                // We need to create column headers in the first row
                if (row == 0)
                    p.add(new JLabel(COUNTS[col]));
                else {
                    /*
                     * When the control moves to a new row, check for the
                     * column. In the first column put row headers
                     */
                    if (col == 0) {
                        p.add(new JLabel(CATEGORIES[row - 1]));/*
                                                                 * row will have
                                                                 * at least
                                                                 * value of 1
                                                                 * when control
                                                                 * is at this
                                                                 * line.
                                                                 */
                    } else {
                        form[row - 1][col - 1] = new JRadioButton();
                        bg.add(form[row - 1][col - 1]);/*
                                                         * add this button to
                                                         * the button group
                                                         */
                        p.add(form[row - 1][col - 1]);
                    }
                }
            }// col for loop ends here.
        }// row for loop ends here.
        return p;
    }
    
    private JScrollPane createScrollPane(JPanel panel) {
        JScrollPane scrollPane = new JScrollPane(panel);
    
        /* Add in some JViewports for the column and row headers */
        JViewport jv1 = new JViewport();
        jv1.setView(new JLabel("COL LABEL"));
    
        scrollPane.setColumnHeader(jv1);
    
        JViewport jv2 = new JViewport();
        jv2.setView(new JLabel("ROW LABEL"));
        scrollPane.setRowHeader(jv2);
    
        /* And throw in an information button */
        JButton jb1 = new JButton("?");
        jb1.addActionListener(new ActionListener() {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                String message = "This is an active corner!";
                String title = "Information";
                int type = JOptionPane.INFORMATION_MESSAGE;
                JOptionPane.showMessageDialog(null, message, title, type);
            }// method actionPerformed ends here.
        }// Definition of inner class ActionListener ends here.
        );/* Passing arguments to method addActionListener ends here. */
        scrollPane.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, jb1);
    
        return scrollPane;
    }
    
    
    public static void main(String[] args) {
        new ScrollDemo2();
    }// method main ends here.
    
    public static final String[] COUNTS = { " ", "0-1", "2-5", "6-10", "11-100", "101+" };
    public static final String[] CATEGORIES = { "Household", "Office", "Extended Family",
            "Company (US)", "Company (World)", "Team", "Will",
            "Birthday Card List", "High School", "Country", "Continent",
            "Planet" };
    
    
    }// class ScrollDemo2 ends here.