0

MacでJavaアプリケーションをテストしている最中ですが、非常に奇妙な問題が発生しました。非モーダルダイアログは正常に機能しますが、モーダルダイアログに表示されるチェックボックスは正しくレンダリングされません。

たとえば、2つのラジオボタンがあるウィンドウがあるとします。ダイアログが開くと、最初のダイアログが選択されます。2番目のボタンをクリックすると、突然両方が選択されているように見えます。ダイアログ内の他の場所をクリックすると、レンダリングが修正され、選択したボタンのみが表示されます。

次のコードは私のためにこれを再現します:

package mactest;

import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Main {
  public static void main(String[] args) {
    boolean modal = false;
    if(args.length > 0) {
      modal = args[0].toLowerCase().equals("true");
    }

    TestDialog dlg = new TestDialog(new Frame(), modal);

    dlg.setVisible(true);
  }

  private static class TestDialog extends Dialog {
    private Checkbox cb1;
    private Checkbox cb2;

    private CheckboxGroup cbg;

    public TestDialog(Frame owner, boolean modal) {
      super(owner);

      cbg = new CheckboxGroup();

      cb1 = new Checkbox("One", true, cbg);
      cb2 = new Checkbox("Two", false, cbg);

      this.setLayout(new FlowLayout());
      this.add(cb1);
      this.add(cb2);

      this.setModal(modal);
      this.pack();

      this.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          TestDialog.this.setVisible(false);
          System.exit(0);
        }
      });
    }
  }
}

私がこれをそのように呼ぶならば:

java -cp MacTest.jar mactest.Main false

ダイアログはモーダルではなく、すべてが正常に機能します。ただし、モーダルであると言った場合:

java -cp MacTest.jar mactest.Main true

その後、レンダリングの問題が発生します。

問題を解決するために考えられるすべてのトリック(無効化、doLayout、フォーカスの要求、ボタンが選択されたときにすべてのボタンの状態を明示的に設定するなど)を試しましたが、これまでのところ、私が得たのは唯一のことです。それでうまくいくのは、ダイアログをモーダルにしないことです。残念ながら、それは私のアプリケーションのオプションではありません。

重要な場合、これはJava1.5.0_16を実行しているOSX10.5を実行しているMacBook上にあります。

4

2 に答える 2

0

チェックボックスまたはラジオボタンについて質問していますか?あなたは両方に言及します。

複数除外スコープを作成するには、ButtonGroupクラスを使用する必要があります

于 2009-06-16T16:20:14.927 に答える
0

それは醜いハックですが、私はそれを修正するように見える何かを見つけました。各チェックボックスにアイテムリスナーを追加しました。これらのトリガーが表示されたら、ウィンドウのサイズを1ピクセル変更してから、pack()でinvokeLater()を実行します(ダイアログのサイズは変更できません)。変更されたテストコードは次のとおりです。

package mactest;

import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Rectangle;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Main {
  public static void main(String[] args) {
    boolean modal = false;
    boolean tweak = false;
    if(args.length > 0) {
      modal = args[0].toLowerCase().equals("true");
    }
    if(args.length > 1) {
      tweak = args[1].toLowerCase().equals("true");
    }

    TestDialog dlg = new TestDialog(new Frame(), modal, tweak);

    dlg.setVisible(true);
  }

  private static class TestDialog extends Dialog {
    private Checkbox cb1;
    private Checkbox cb2;

    private CheckboxGroup cbg;

    public TestDialog(Frame owner, boolean modal, boolean tweak) {
      super(owner);

      cbg = new CheckboxGroup();

      cb1 = new Checkbox("One", true, cbg);
      cb2 = new Checkbox("Two", false, cbg);

      this.setLayout(new FlowLayout());
      this.add(cb1);
      this.add(cb2);

      this.setModal(modal);
      this.pack();

      if(tweak) {
        cb1.addItemListener(new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            onSelection();
          }
        });
        cb2.addItemListener(new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            onSelection();
          }
        });
      }

      this.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          TestDialog.this.setVisible(false);
          System.exit(0);
        }
      });
    }

    private void onSelection() {
      Rectangle bounds = this.getBounds();
      this.setBounds(bounds.x, bounds.y, bounds.width + 1, bounds.height);
      EventQueue.invokeLater(new Runnable() {
        public void run() {
          TestDialog.this.pack();
        }
      });
    }
  }
}

サイズ変更可能なコンポーネントの場合、pack()を呼び出す代わりに、サイズを事前に調整して復元する必要があります。

Windowsでは、選択を変更したときにダイアログがちらつくことがありましたが、Macではまったく目立ちませんでした。

于 2009-06-18T20:20:55.987 に答える