2

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

我想得到的输出

而不是那个输出,我得到了一个类似于下面的输出:

我现在得到的错误输出

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

  1. 我没有得到垂直和水平的滚动条。
  2. 我没有得到面板“p”中每一行的行标题。
  3. 格式似乎也受到干扰。当程序启动时,单选按钮是不可见的,直到我将鼠标移到它们上面。

此代码来自使用 Eclipse IDE 的 O'REILLY 的 Java Swing 书(第 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。/ 包 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.
4

1 回答 1

0

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

一些外卖提示:

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

这是您修改后的代码:

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.
于 2014-01-31T22:43:48.887 回答