1

test2 というパッケージの Test2.java というファイルに次のコードがあります。

package test2;

import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class Test2 {
    public static void main(String[] args) {
        int k = 7;
        while(true) {
            try {
                JFrame mainWindow = new HtmlWindow(k);
            } catch(UnsupportedOperationException numberChosen) {
                JOptionPane.showInternalMessageDialog(null, "information",
                        "You clicked on number " + numberChosen, 
                        JOptionPane.INFORMATION_MESSAGE);
                Integer l = new Integer("0" + numberChosen);
            }
        }
    }
}

同じパッケージの HtmlWindow というファイルに次のコードがあります。

package test2;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;

class HtmlWindow extends JFrame implements MouseListener {
    public HtmlWindow(int k) throws UnsupportedOperationException {
        super("blah");
        setSize(150, 200);
        Container content = getContentPane();
        content.setLayout(new FlowLayout());
        JLabel[] coloredLabel = new JLabel[k];
        String[] labelText = new String[k];
        for(int i=0; i<=k-1; i++) {
            labelText[i] = "<html><img src = "
                + "\"http://images.nycsubway.org/bullets/lines/"
                + (i+1)
                + ".GIF\">"
                + "</html>";
            coloredLabel[i] = new JLabel(labelText[i]);
            coloredLabel[i].setName((i + 1) + " ");
            coloredLabel[i].addMouseListener(this);
            addMouseListener(this);
            content.add(coloredLabel[i]);
        }
        this.setVisible(true);
        while(true) {
        }
    }

@Override
public void mousePressed(MouseEvent me) {
}

@Override
public void mouseReleased(MouseEvent me) {
}

@Override
public void mouseEntered(MouseEvent me) {
}

@Override
public void mouseExited(MouseEvent me) {
}

@Override
public void mouseClicked(MouseEvent me) {
    throw new UnsupportedOperationException(me.getComponent().getName());
}
}

これを実行すると、期待どおりにウィンドウに数字の写真が表示されますが、それらのいずれかをクリックすると、スローされた例外がキャッチされません。どうしてこれなの?ポインターは、HTMLWindow コンストラクターの "while" セクションを回る必要があり、したがって "try" セクション内にあるため、キャッチする必要があります。私の推測では、これは、mouseClicked セクションが HTMLWindow コンストラクター内にないためであり、例外が何らかの形で try ブロックの外側にスローされているのではないでしょうか?

これが、GUI から元のプログラムに情報を戻す最善の方法ではない場合、どのような方法があるでしょうか? 「戻る」を使用しているとは思わない

  • コンストラクターには戻り値の型がありません
  • mouseClicked はコンストラクタ内にありません

余談ですが、数字などの上に移動したときにプログラムに何もさせたくありません。それらをクリックするだけです。では、なぜ mousePressed ブロックなどが必要なのですか? プログラムはそれらなしではコンパイルされません。このまま空白のままでいいのでしょうか?

4

1 に答える 1

2

ポインターは、HTMLWindow コンストラクターの "while" セクションを回る必要があり、したがって "try" セクション内にあるため、キャッチする必要があります。

それはまだtryブロック内にありますが、明らかにそのwhileループは例外をスローしませんよね?

あなたは次のように仮定しているようです:

  • UI は別のスレッドで実行されます。
  • UI スレッドでスローされた例外は、何らかの形でコンストラクターを含むスレッドにマーシャリングされます。

最初の箇条書きについてはわかりませんが、2 番目の箇条書きは間違いなく正しくありません。(そして、タイトなwhile(true)ループは決して正しい解決策ではありません...)

これが、GUI から元のプログラムに情報を戻す最善の方法ではない場合、どのような方法があるでしょうか?

何を達成しようとしているのかは明確ではありませんが、一般的に GUI は「イベント指向」です。そのため、他のコードがフックできるある種のリスナーを GUI に公開させる方法を考える必要があります。

余談ですが、数字などの上に移動したときにプログラムに何もさせたくありません。それらをクリックするだけです。では、なぜ mousePressed ブロックなどが必要なのですか? プログラムはそれらなしではコンパイルされません。このまま空白のままでいいのでしょうか?

MouseListener直接実装する代わりに、アダプタ クラスの 1 つ (例: MouseAdapter) を使用して、関連するインターフェイスを実装し、no-op 実装を提供します。MouseAdapter しかし、明らかに、ウィンドウを 拡張することはできませんJFrame。ここには、2 つの別個のクラスが必要です。

于 2012-08-01T16:18:02.170 に答える