Визуальные артефакты, появляющиеся на JPanel
Я пытаюсь создать программу с 2 JPanel
, используя BorderLayout
. Центральная панель предназначена для случайного рисования прямоугольника, а южная - для кнопок.
Я получаю странное изображение кнопки в верхнем левом углу JFrame
всякий раз, когда я навожу курсор мыши на Северную или Южную кнопку. Я провел небольшое исследование и выяснил, что это может быть причиной наличия прозрачного фона. Я попытался использовать super.paintComponent(g)
для панели, но остальные прямоугольники, нарисованные ранее исчезнуть. Мне нужно, чтобы прямоугольники оставались в JPanel
, но не странное изображение в левом верхнем углу.
public class TwoBRandomRec extends JFrame{
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
TwoBRandomRec rec = new TwoBRandomRec();
rec.setSize(500,500);
rec.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rec.setVisible(true);
}
public TwoBRandomRec() {
//Create the buttons
JButton north = new JButton("North");
JButton south = new JButton("South");
DrawPanel drawPanel = new DrawPanel(500,500);
JPanel southP = new JPanel();
southP.add(south);
southP.add(north);
this.add(drawPanel, BorderLayout.CENTER);
this.add(southP, BorderLayout.SOUTH);
this.setTitle("TwoButtonRandomRec");
this.pack();
}
public class DrawPanel extends JPanel {
private static final long serialVersionUID = 1L;
private Random rand = new Random();
private int x,y,xSize,ySize;
private int height,width;
public DrawPanel(int w,int h) {
width = w;
height = h;
}
public void RandomX(){
x=rand.nextInt(width-1);
xSize=rand.nextInt(width-x);
}
public void RandomY(){
y=rand.nextInt(height-1);
ySize=rand.nextInt(height-y);
}
public Color RandomColour(){
rand.nextInt(height);
return new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255));
}
@Override
protected void paintComponent(Graphics g) {
RandomX();
RandomY();
g.setColor(RandomColour());
g.fillRect(x, y, xSize, ySize);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
repaint();
}
}
}
1 ответ:
Ты не звонишь
super.paintComponent
protected void paintComponent(Graphics g) { super.paintComponent(g); // <-- Insert me here and watch problem go away RandomX(); RandomY(); g.setColor(RandomColour()); g.fillRect(x, y, xSize, ySize); try { Thread.sleep(50); // <-- This is an INCREDIBLY bad idea, NEVER, EVER do this } catch (InterruptedException e) { } repaint(); // <-- This is a bad idea, watch CPU max out... }
Вы обязаны вызвать
super.paintComponent
, чтобы убедиться, что цепочка рисования поддерживается правильно и происходят такие вещи, как непрозрачность и очистка графического контекста.Объект
Graphics
разделяется между компонентами через один проход перекраски, несоблюдение правильной цепочки покраски приведет к, ну, таким проблемам, как вашаНикогда не обновляйте пользовательский интерфейс в любом случае из любого метода
paint
(это включает вызовrepaint
), это просто вызывает ваш методpaint
будет вспоминаться снова и снова...пока ваш процессор не достигнет 100% и программа не зависнет.Никогда, никогда не делайте никаких трудоемких или блокирующих операций в рамках методов
paint
(или пользовательского интерфейса в целом), это сделает его похожим на программу, как зависший и расстроит пользователей (вы думаете, орды зомби плохие :P). Блокировка таким образом предотвращает EDT от ответа на запросы paint...Я бы рекомендовал прочитать до конца: