У меня есть пользовательский JPanel, который не вызывает super.paintComponent() в его переопределенном методе paintComponent. Я знаю, что это во многих ситуациях не рекомендуется, но мне интересно, почему следующие:эффекты не вызова super.paintComponent в пользовательских JPanel
встречается,Когда я запускаю два потока, что каждый создать JFrame и настраиваемую панель, панели как-то смешать их содержимое. В этом примере программа создаст два кадра, каждый из которых отобразит панель с «ONE» и «TWO» в качестве содержимого. Но я ожидал, что у меня будет один кадр с «ONE» и один кадр с «TWO» в качестве контента.
public class CustomPanel extends JPanel implements Runnable {
public static void main(String[] args) {
//create two threads constantly repainting the custom panel
//expected two panels with different content
//but got two panels with same content
new Thread(new CustomPanel("ONE", 20)).start();
new Thread(new CustomPanel("TWO", 40)).start();
}
/** creates a frame and adds the custom panel with specified text **/
public CustomPanel(String text, int y) {
setPreferredSize(new Dimension(200,50));
this.text = text;
this.y = y;
JFrame f = new JFrame(text);
f.add(this);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
private String text;//the text to draw
private int y;//where to draw
/** draw the component **/
@Override
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.drawString("Hello " + text, 50, y);//this line will be drawn twice on each panel (with text and y from the other)
g.dispose();
}
/** constantly repaint the custom panels **/
@Override
public void run() {
while (true) {
this.repaint();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Result
Frame1 Frame2
++++++++++++++++++ ++++++++++++++++++
+ Hello ONE + + Hello ONE +
+ Hello TWO + + Hello TWO +
++++++++++++++++++ ++++++++++++++++++
Expected Result
Frame1 Frame2
++++++++++++++++++ ++++++++++++++++++
+ Hello ONE + + +
+ + + Hello TWO +
++++++++++++++++++ ++++++++++++++++++
Так как на земле две панели окрашены таким же образом?
Примечание стороны 1: вызов super.paint() в краске() сделает пользовательские панели выглядят по-разному
Примечание стороны 2: Перемещение рамки двух другой экран, сделает его панель рисовать, как и ожидалось (только будет показан его собственный текст), тогда как другой останется прежним.
Update Этот тест был сделан на ОС Windows 8.1 и JRE 1.7
Невозможно воспроизвести ваши наблюдения (может быть зависит от ОС?). Некоторые другие соображения a) создайте свой пользовательский интерфейс на EDT b) не удаляйте объект Graphics в методе рисования. c) переопределить 'paintComponent', а не' paint' – copeg
Возможно, задний буфер снова используется (я не могу его воспроизвести). Вы не подчиняетесь [непрозрачному контракту] (http://stackoverflow.com/questions/2451990/setopaquetrue-false-java), поэтому сломанный рендеринг не является неожиданностью. – kiheru
Вы не создаете свой пользовательский интерфейс на EDT, так что не удивительно, что происходят странные вещи. Я предлагаю вам проверить книгу/учебник о том, как использовать Swing. Это не так просто, как вы могли бы подумать вначале (то же самое случилось со мной кстати). – m0skit0