2013-05-17 2 views
1

В настоящее время я пытаюсь нарисовать фигуру, нажав кнопку. Мои проблемы возникают, когда я нажимаю кнопку, и она не отображается на панели, но я знаю, что это рисунок, потому что он проходит через цикл.Рисование фигуры, щелкнув JButton

Розыгрыш будет происходить, когда я прошу панели, чтобы сделать его в конструкторе, но не внутри кнопки, внутри конструктора

Если я поставил код в методе «материал()» в конструкторе его все будет хорошо.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class MainFrame{ 
    public static void main(String[]args){ 
     MainFrame f = new MainFrame(); 
    } 
public JFrame frame = new JFrame(); 
public JPanel panel = new JPanel(new BorderLayout()); 
public MainFrame(){ 
    JButton button1 = new JButton("Shweet Button"); 
    button1.setBounds(185, 10, 130, 20); 
    frame.setBounds(1680/4,1050/4,500, 500); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setResizable(false); 
    frame.add(panel); 
    panel.setBackground(Color.black); 
    frame.setVisible(true); 
    frame.getContentPane().setLayout(null); 
    frame.add(button1); 
    button1.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      stuff(); 
     } 
    }); 
} 
public void stuff(){ 
    for(int i = 0;i<1000;i++){ 
     panel.add(new paintComponent()); 
     panel.setBackground(Color.black); 
     frame.repaint(); 
     try { 
      Thread.sleep(80); 
     } catch (InterruptedException e1){e1.printStackTrace();} 
    } 
} 
static class paintComponent extends JComponent{ 
    public int options; 
    public void paint(Graphics g){ 
     Graphics2D g2 = (Graphics2D)g; 
     g2.setColor(Color.white); 

     if(options == 0){ 
      options = 1; 
      g2.drawOval(50, (JFrame.HEIGHT/2)+100, 50, 50); 
      g2.drawOval(60, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.fillOval(60, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.drawOval(80, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.fillOval(80, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.drawArc(65, (JFrame.HEIGHT/2)+130, 100, 0, 140, 30); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+150, 75, (JFrame.HEIGHT/2)+220); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+180, 100, (JFrame.HEIGHT/2)+160); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+180, 65, (JFrame.HEIGHT/2)+210); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+220, 50, (JFrame.HEIGHT/2)+260); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+220, 100, (JFrame.HEIGHT/2)+260); 
     }else if(options == 1){ 
      options = 0; 
      g2.drawOval(50, (JFrame.HEIGHT/2)+100, 50, 50); 
      g2.drawOval(60, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.fillOval(60, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.drawOval(80, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.fillOval(80, (JFrame.HEIGHT/2)+110, 8, 8); 
      g2.drawArc(65, (JFrame.HEIGHT/2)+130, 100, 0, 140, 30); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+150, 75, (JFrame.HEIGHT/2)+220); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+180, 100, (JFrame.HEIGHT/2)+180); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+180, 65, (JFrame.HEIGHT/2)+210); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+220, 50, (JFrame.HEIGHT/2)+260); 
      g2.drawLine(75, (JFrame.HEIGHT/2)+220, 100, (JFrame.HEIGHT/2)+260); 
     } 
    } 
} 
} 
+0

Вы заблокировать поток событий Dispatching, который мешает ему обновлять UI – MadProgrammer

+0

, вам нужно разместить столько кода? Будет ли достаточно, если у вас есть только одна строка drawOvel для каждого из двух вариантов? –

+0

Applcation Похож на выполнение Исполнение –

ответ

3

Вы блокируете Диспетчерскую тему событий, которая отвечает за, помимо прочего, обработку запросов краски.

Вы никогда не должны ничего подобного делать ...

for(int i = 0;i<1000;i++){ 
    panel.add(new paintComponent()); 
    panel.setBackground(Color.black); 
    frame.repaint(); 
    try { 
     Thread.sleep(80); 
    } catch (InterruptedException e1){e1.printStackTrace();} 
} 

В EDT. Помимо того, что вы добавляете несколько новых компонентов в свой пользовательский интерфейс каждые 80 миллисекунд, вы также блокируете поток, который отвечает за обновление вашего экрана ...

За дополнительной информацией обращайтесь к Concurrency in Swing.

Анимация этого типа должна обрабатываться javax.swing.Timer.

Пользовательское окрашивание должно выполняться в методе paintComponent, как правило. Вы также должны сначала позвонить super.paintXxx, как само собой разумеющееся. В фоновом режиме много работы, о которой нужно позаботиться, особенно если компонент прозрачен.

Отъезд Performing Custom Painting и Painting in AWT and Swing для более подробной информации.

Сохраните свое здравомыслие и узнайте, как использовать менеджеры макетов, они облегчат вашу жизнь в долгосрочной перспективе.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class MainFrame { 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       MainFrame f = new MainFrame(); 
      } 
     }); 
    } 
    public JFrame frame = new JFrame(); 
    public JPanel panel = new JPanel(new BorderLayout()); 
    private WavePane waver; 

    public MainFrame() { 
     waver = new WavePane(); 
     JButton button1 = new JButton("Shweet Button"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(panel); 
     panel.setBackground(Color.black); 
     frame.add(button1, BorderLayout.SOUTH); 
     button1.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       stuff(); 
      } 
     }); 
     panel.add(waver); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public void stuff() { 
//  for (int i = 0; i < 1000; i++) { 
//   panel.add(new paintComponent()); 
//   panel.setBackground(Color.black); 
//   frame.repaint(); 
//   try { 
//    Thread.sleep(80); 
//   } catch (InterruptedException e1) { 
//    e1.printStackTrace(); 
//   } 
//  } 
     waver.walk(!waver.isWaving()); 
    } 

    public class WavePane extends JComponent { 

     private int options; 
     private Timer timer; 

     public WavePane() { 
      setOpaque(false); 
      timer = new Timer(80, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("tick"); 
        options++; 
        repaint(); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 
     } 

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

     public void walk(boolean walk) { 
      if (walk) { 
       timer.start(); 
      } else { 
       timer.stop(); 
      } 
     } 

     public boolean isWaving() { 
      return timer.isRunning(); 
     } 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setColor(Color.white); 

      int height = getHeight(); 

      if (options % 2 == 0) { 
       g2.drawOval(50, 100, 50, 50); 
       g2.drawOval(60, 110, 8, 8); 
       g2.fillOval(60, 110, 8, 8); 
       g2.drawOval(80, 110, 8, 8); 
       g2.fillOval(80, 110, 8, 8); 
       g2.drawArc(65, 130, 100, 0, 140, 30); 
       g2.drawLine(75, 150, 75, 220); 
       g2.drawLine(75, 180, 100, 160); 
       g2.drawLine(75, 180, 65, 210); 
       g2.drawLine(75, 220, 50, 260); 
       g2.drawLine(75, 220, 100, 260); 
      } else { 
       g2.drawOval(50, 100, 50, 50); 
       g2.drawOval(60, 110, 8, 8); 
       g2.fillOval(60, 110, 8, 8); 
       g2.drawOval(80, 110, 8, 8); 
       g2.fillOval(80, 110, 8, 8); 
       g2.drawArc(65, 130, 100, 0, 140, 30); 
       g2.drawLine(75, 150, 75, 220); 
       g2.drawLine(75, 180, 100, 180); 
       g2.drawLine(75, 180, 65, 210); 
       g2.drawLine(75, 220, 50, 260); 
       g2.drawLine(75, 220, 100, 260); 
      } 
     } 
    } 
} 

Вы не должны использовать JFrame.HEIGHT это на самом деле не имеет ничего общего с высотой кадров, но является частью поддержки ImageObserver ... или любого типа магического числа по этому вопросу

+0

Ты потрясающий! У меня возникли проблемы с переориентацией метода paintComponent, и я понял, что его нужно защищать, idk, что это значит, но спасибо за то, что выбрали лишнюю милю и помогли мне! – Loligans

+1

Метод 'protected' означает, что вызов метода может только класс, объявленный им, класс в том же пакете и любые дочерние классы, которые его расширяют. Проверьте [Управление доступом к членам класса] (http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) для получения более подробной информации. – MadProgrammer

+0

использование зарезервировано Java-методы имена 'static class ** paintComponent * * расширяет JComponent {' – mKorbel