2

次のコードでは、本来あるべき出力が得られません。それが与えるべき出力は以下に示されています:

取得したい出力

その出力の代わりに、次のような出力が得られました。

私が今得ている間違った出力

私が得ていないことに気づいたことは次のとおりです。

  1. ScrollBarsが垂直方向と水平方向の両方に表示されません。
  2. パネル「p」にある各行の行ヘッダーが取得されません。
  3. フォーマットも乱れているようです。プログラムが起動すると、マウスをボタンの上に移動するまでラジオボタンは表示されません。

このコードは、EclipseIDEを使用したO'REILLYのJavaSwingブック(第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. 特定のコンポーネントを 1 つのメソッドだけで使用するようにしてください。あなたのコードは、コンストラクターと 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 に答える