• title: Swing Bug keywords: [Java, Swing] description: Swing関連で注目しているバグIDへのリンク、メモなど author: aterai pubdate: 2018-01-22

概要

Swing関係で個人的に注目しているバグIDへのリンクなどをメモしています。

未修整

Application uses higher CPU in 8u161/8u162

右Altキーが効かない

MetalLookAndFeelでのJComboBoxとJToolTip

  • ドロップダウンリストを開いた状態でツールチップが表示されると描画がおかしくなる場合がある
    • MetalLookAndFeelのみ
    • ドロップダウンリストがHeavyWeightWindowLightWeightWindowかは無関係

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class CustomJComboBoxTest2 {
  public JComponent makeUI() {
    JComboBox<String> box = new JComboBox<>();
    box.addItem("Item 1");
    box.addItem("Item 2");
    box.setToolTipText("TooTip");

    JPanel p = new JPanel(new BorderLayout());
    p.setBorder(BorderFactory.createEmptyBorder(60, 20, 60, 20));
    p.add(box);
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new CustomJComboBoxTest2().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

JToolBarに配置したJButtonのフォーカス描画

NimbusLookAndFeelでのJComboBoxの推奨サイズ

  • java - Swing (JComboBox) bug? printing dimension - Stack Overflow
    • JComboBoxの時点と、JFrameに追加してJFrame#pack()もしくはJFrame.setSize(...)後で、JComboBoxの推奨サイズ(幅)が異なる?
    • NimbusLookAndFeelのみの現象?
    • setEditable(true)にすると高さが異なる...
  • JComboBox#getPreferredSize()を呼ぶと項目の文字列長を検索して、cachedMinimumSizeにサイズがキャッシュされる
  • ArrowButtonの幅がデフォルト16JComboBox用は19と異なる
  • SynthArrowButton#getPreferredSize(JComponent)で、context.getStyle().getInt(context, "ArrowButton.size", 16);が呼ばれている
import java.awt.*;
import javax.swing.*;

public class NimbusComboBoxSizeTest {
  public JComponent makeUI() {
    String[] model = {"Average"};

    JPanel p0 = new JPanel();
    JComboBox<String> combo0 = new JComboBox<>(model);
    p0.add(combo0);

    JPanel p1 = new JPanel();
    JComboBox<String> combo1 = new JComboBox<>(model);
    p1.add(combo1);

    Box box = Box.createVerticalBox();
    box.add(p0);
    box.add(p1);

    EventQueue.invokeLater(() -> System.out.println("combo0: " + combo0.getPreferredSize()));
    System.out.println("combo1: " + combo1.getPreferredSize());

    JPanel p = new JPanel(new BorderLayout());
    p.add(box, BorderLayout.NORTH);

    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(() -> createAndShowGUI());
  }
  public static void createAndShowGUI() {
    try {
      for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
        if ("Nimbus".equals(laf.getName())) {
          UIManager.setLookAndFeel(laf.getClassName());
          UIDefaults d = UIManager.getLookAndFeelDefaults();
          System.out.println("ArrowButton.size: " + d.getInt("ArrowButton.size"));
          System.out.println("ComboBox.arrowButton.size: " + d.getInt("ComboBox:\"ComboBox.arrowButton\".size"));
          //どちらかのコメントを外して値を揃えてやると、以下の現象は修正される?
          //d.put("ComboBox:\"ComboBox.arrowButton\".size", 16);
          //d.put("ArrowButton.size", 19);
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new NimbusComboBoxSizeTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

高解像度でJOptionPaneのアイコンが欠ける

  • java - Bad Swing UI scaling on high resolution (MS Surface) - Stack Overflow
    • Surface Pro 3でテキスト文字サイズを150%に設定し、JOptionPaneWindowsLookAndFeelで表示すると、アイコンが欠けるバグ?
    • 以下のようにOptionPane.minimumSizeを設定しても解消しない
    • レイアウトでおかしくなっているのではなく、取得するアイコン自体が欠けている?
import java.awt.*;
import javax.swing.*;

public class OptionPaneResolutionTest {
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
      e.printStackTrace();
    }
    Dimension defaultSize = UIManager.getDimension("OptionPane.minimumSize");
    System.out.println("OptionPane.minimumSize default: " + defaultSize);
    int sr = Toolkit.getDefaultToolkit().getScreenResolution();
    float dpi = System.getProperty("os.name").startsWith("Windows") ? 96f : 72f;
    float sot = sr / dpi;
    System.out.format("%d%%%n", (int)(sot * 100));
    Dimension mind = new Dimension((int)(defaultSize.width * sot),
                                   (int)(defaultSize.height * sot));
    System.out.println("OptionPane.minimumSize: " + mind);
    UIManager.put("OptionPane.minimumSize", mind);

    JOptionPane.showMessageDialog(null, "msg", "Information", JOptionPane.INFORMATION_MESSAGE);
  }
}

修正済み

親フレームのドラッグ中にJWindowでクラッシュ

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Main2 {
  private static Robot robot;
  public static void main(String... args) throws Exception {
    robot = new Robot();
    robot.setAutoDelay(100);
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
    EventQueue.invokeAndWait(new Runnable() {
      @Override public void run() {
        Point pt = new Point(50, 10);
        robot.mouseMove(pt.x, pt.y);
        robot.mousePress(InputEvent.BUTTON1_MASK);
        pt.translate(50, 50);
        robot.mouseMove(pt.x, pt.y);
        //robot.mouseRelease(InputEvent.BUTTON1_MASK);
      }
    });
  }
  public static void createAndShowGUI() {
    final JFrame f = new JFrame();
    f.add(new JLabel("Try JFrame draging 2sec"));
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setSize(320, 240);
    f.setVisible(true);
    final JWindow w = new JWindow(f);
    w.add(new JButton("button"));
    w.pack();
    Timer t = new Timer(2000, new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        w.setVisible(true);
      }
    });
    t.setRepeats(false);
    t.start();
  }
}

TimSortでレイアウトをソート中に例外発生

  • java - swing gui flickering white error - Stack Overflowのサンプルを試していたら面白い挙動に遭遇。
  • JDK1.7.0_21
    • IllegalArgumentException: Comparison method violates its general contract!
      Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!
      	at java.util.TimSort.mergeLo(TimSort.java:747)
      	at java.util.TimSort.mergeAt(TimSort.java:483)
      	at java.util.TimSort.mergeCollapse(TimSort.java:410)
      	at java.util.TimSort.sort(TimSort.java:214)
      	at java.util.TimSort.sort(TimSort.java:173)
      	at java.util.Arrays.sort(Arrays.java:659)
      	at java.util.Collections.sort(Collections.java:217)
    • フレームのリサイズで上下左右に余白?
  • JDK1.6.0_41
    • フレームのリサイズで右と下に余白?
import java.awt.*;
import javax.swing.*;

public class Gui {
  public JComponent makeUI() {
    JPanel p = new JPanel(new GridLayout(22,12,10,10));
    p.setBackground(Color.WHITE);
    p.setBorder(BorderFactory.createLineBorder(Color.BLUE, 10));
    for (int i = 0; i < 22; i++) {
      for (int j = 0; j < 12; j++) {
        JLabel label = new JLabel();
        label.setBorder(BorderFactory.createLineBorder(Color.RED));
        label.setBackground(Color.GRAY);
        label.setOpaque(true);
        //label.setPreferredSize(new Dimension(50, 50));
        p.add(label);
      }
    }
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new Gui().makeUI());
    f.setSize(320, 240);
    //f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

再現不可

WebStartでCPU 100%

  • 再現しなくなった

参考リンク

コメント