Как устранить эту ошибку, когда один класс, если я использую его, вызывает заражение интерфейсов других классов
Мой случай:
У меня странная ошибка
Мне нужно использовать 2 класса из 1 основного класса, который выглядит следующим образом:
1 основной класс, который водит оба класса
YumYumYum
2 других класса, которые являются только пользовательскими интерфейсами, как показано ниже:
а)
MyJSlider
главный создатель ошибокб)
Volume
второй класс, который просто показывает черное окно с зеленым индикатором на нем
Теперь я подготовил SSCCE в одном файле, и demo.xml также доступен здесь.
Проблема:
Если я закомментирую строку private MyJSlider _______BUG__BUG__BUG_______ = new MyJSlider();
это работает, но когда я использую это, это вызывает все проблемы. Как я могу это исправить?
import java.awt.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.plaf.synth.SynthLookAndFeel;
public class YumYumYum {
//
// Step 1: using 2 class from here
//
private MyJSlider _______BUG__BUG__BUG_______ = new MyJSlider();
private static JFrame f = new JFrame();
public YumYumYum() {
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setLayout(new FlowLayout());
f.setPreferredSize(new Dimension(300, 200));
f.getContentPane().add(new JButton("Show me as Swing only - Then i am correct"));
f.pack();
f.setVisible(true);
}
public void test() {
Volume a = new Volume();
a.up(100);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
YumYumYum s = new YumYumYum();
s.test();
}
});
}
//
// Step 2: Creates the problem
//
public class MyJSlider extends JSlider {
public MyJSlider() {
try {
SynthLookAndFeel laf = new SynthLookAndFeel();
//laf.load(MyJSlider.class.getResourceAsStream("/ui/demo.xml"), MyJSlider.class);
laf.load(new URL("file:///var/tmp/demo.xml"));
UIManager.setLookAndFeel(laf);
} catch (Exception e) {
e.printStackTrace();
}
setOrientation(JSlider.VERTICAL);
//setMinimum(-24);
setMaximum(12);
setOpaque(false);
}
}
//
// Step 3: Does not show its actual user interface when Step 2 is involved
//
public class Volume extends JWindow {
private JPanel panelFirst;
private JProgressBar a;
public Volume() {
setLayout(new BorderLayout());
setBounds(10, 40, 350, 60);
panelFirst = new JPanel();
panelFirst.setBackground(Color.BLACK);
panelFirst.setLayout(new FlowLayout(FlowLayout.LEFT, 8,5));
a = createJP(100);
panelFirst.add(a);
add(panelFirst);
setVisible(true);
setAlwaysOnTop(true);
}
public JProgressBar createJP(int input) {
JProgressBar jp = new JProgressBar(JProgressBar.VERTICAL, 0, 100);
jp.setPreferredSize(new Dimension(15, 50));
jp.setValue(input);
jp.setBackground(Color.RED);
jp.setVisible(true);
return jp;
}
public void up(int input) {
a.setForeground(Color.GREEN);
}
}
}
Следовать за:
- Протестировано в Java 6 и Java 7 оба одинаковых результата в Linux
2 ответа
Альтернативное решение этой проблемы приведено ниже:
Поместите это там, где Synth не является предпочтительным.
//
// Step 3: Makeing this work
//
public class Volume extends JWindow {
private JPanel panelFirst;
private JProgressBar a;
public Volume() {
try {
// Set cross-platform Java L&F (also called "Metal")
UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName());
}
catch (UnsupportedLookAndFeelException e) {
// handle exception
}
catch (ClassNotFoundException e) {
// handle exception
}
catch (InstantiationException e) {
// handle exception
}
catch (IllegalAccessException e) {
// handle exception
}
setLayout(new BorderLayout());
setBounds(40, 40, 350, 60);
panelFirst = new JPanel();
panelFirst.setBackground(Color.BLACK);
panelFirst.setLayout(new FlowLayout(FlowLayout.LEFT, 8,5));
a = createJP(100);
panelFirst.add(a);
add(panelFirst);
setVisible(true);
setAlwaysOnTop(true);
}
public JProgressBar createJP(int input) {
JProgressBar jp = new JProgressBar(JProgressBar.VERTICAL, 0, 100);
jp.setPreferredSize(new Dimension(15, 50));
jp.setValue(input);
jp.setBackground(Color.BLACK);
jp.setVisible(true);
return jp;
}
public void up(int input) {
a.setForeground(Color.GREEN);
}
}
Я подозреваю, что звонок UIManager.setLookAndFeel
портит ваш интерфейс (я проверял это под Mac OSx и у меня не было проблем...)
Попробуйте сделать звонок setLookAndFeel
в main
метод перед invokeLater
вызов...
public static void main(String[] args) {
SynthLookAndFeel laf = new SynthLookAndFeel();
//laf.load(MyJSlider.class.getResourceAsStream("/ui/demo.xml"), MyJSlider.class);
laf.load(new URL("file:///var/tmp/demo.xml"));
UIManager.setLookAndFeel(laf);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
YumYumYum s = new YumYumYum();
s.test();
}
});
}
Это может помочь