2012-12-12 2 views
2

Мое приложение не ориентировано на JFrame, оно просто использует один для вывода. Мне просто нужно сказать, чтобы рисовать прямоугольник здесь, очистить экран сейчас, несколько сотен раз. Чтобы сделать это, я написал следующий код в своей основной статье, который, по моему мнению, должен очистить весь JFrame до красивого голубого цвета фона.Картина на JFrame без расширения

JFrame frame = new JFrame("Maze Master Premium Super-Deluxe V199.39"); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
int resolution = 20; 
int frameWidth = horiz * resolution; 
int frameHeight = vert * resolution; 
frame.setMinimumSize(new Dimension(frameWidth, frameHeight)); 
frame.setSize(frameWidth, frameHeight); 
frame.pack(); 
frame.setVisible(true); 
frame.toFront(); 

Graphics g = frame.getGraphics(); 
g.setPaintMode(); 
g.setColor(Color.BLUE); 
//Clear background 
g.fillRect(0, 0, frameWidth, frameHeight); 
frame.update(g); 

Но когда я запустил это, JFrame отображает его цвет фона со светлым сером по умолчанию. Должен ли я иметь расширение JFrame для класса, или достаточно использовать frame.update (g), и я просто делаю что-то еще неправильно?

+1

Литература: [Выборочная живописи] (http://docs.oracle.com/javase/tutorial/uiswing/painting/), [Параллелизм в свинг] (http://docs.oracle.com/javase /tutorial/uiswing/concurrency/index.html). – ignis

+1

1. Не вызывайте методы AWT или Swing из потоков, отличных от Thread Dispatch Thread. 2. Подкласс JPanel (не JFrame) и переопределить paintComponent() для вызова super.paintComponent(), а затем выполнить собственный чертеж. – ignis

+2

Вы можете использовать «frame.getContentPane(). SetBackground (Colour.BLUE)». Это экономит ненужный прямоугольник. – cworner1

ответ

3

С вашего вопроса трудно понять, что именно вы пытаетесь достичь. Вы просто хотите изменить цвет фона фрейма или выполнить какую-то пользовательскую покраску ???

Этот Graphics g = frame.getGraphics() никогда не является хорошей идеей. Помимо того факта, что возможно, что getGraphics может вернуться null, графика не имеет аналогов в Java, что означает, что графический контекст, который вы используете для рисования, может меняться между циклами рисования, вы никогда не должны полагаться на него или поддерживать ссылку на него.

Помимо ошибочного подхода, JFrame содержит числовые компоненты, которые отображаются поверх него, поэтому даже если этот метод работал, вы не увидите никакой разницы, потому что кадр фактически покрывается другими компоненты (JRootPane и его содержимое)

Настраиваемая окраска должна выполняться в одном из методов краски Component.

В следующем примере используется ряд методов для изменения и обновления содержимого фрейма.

enter image description here

Во-первых, он заменяет панель контента с нашего компонента. Это всегда необходимо, но поскольку я выполняю обычную покраску на кадре, это было проще всего. Я мог бы просто добавить PaintPane к кадру, чтобы получить аналогичный результат.

Во-вторых, я использую setBackground, чтобы изменить фон моего компонента.

В-третьих, я переопределяю paintComponent, чтобы выполнить пользовательскую покраску на моем компоненте.

public class SimplePaint01 { 

    public static void main(String[] args) { 
     new SimplePaint01(); 
    } 

    public SimplePaint01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.setContentPane(new PaintPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class PaintPane extends JPanel { 

     private int angle = 0; 
     private Rectangle shape = new Rectangle(0, 0, 100, 100); 

     public PaintPane() { 
      setBackground(Color.RED); 
      Timer timer = new Timer(16, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        angle += 5; 
        repaint(); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 

      int x = ((getWidth() - shape.width)/2); 
      int y = ((getHeight() - shape.height)/2); 

      shape.x = x; 
      shape.y = y; 

      g2d.setColor(Color.BLUE); 
      g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angle), x + (shape.width/2), y + (shape.height/2))); 
      g2d.fill(shape); 

      g2d.dispose(); 
     } 

    } 

} 
+0

Итак, JFrame постоянно перекрашивается? Вот проблема: мне нужен материал, который я рисую, чтобы рисовать, и мне нужно нарисовать переменное количество вещей из приложения, которое постоянно добавляет строки и круги в фрейм. Есть ли способ удержать его от перекраски? – Miles

+1

Простой ответ - Нет, вы не можете (и не должны) остановить Swing от попытки перекрасить.То, что вам нужно сделать, это либо нарисовать то, что вы хотите для резервного буфера (например, «BufferedImage»), и нарисовать его каждый раз, когда происходит перерисовка, или регенерируйте представление каким-то образом. – MadProgrammer

+1

* «Что вам нужно сделать, либо нарисовать то, что вы хотите для буфера поддержки (например,« BufferedImage ») ..» * .. затем отобразить его в 'JLabel' (это еще одна стратегия). –

Смежные вопросы