2015-12-15 3 views
0

Хорошо, поэтому я пытаюсь сделать программу смайликов, когда она начинается вначале, она должна показывать по умолчанию смайлик (эта часть работает, и это здорово, я думаю)Как рисовать из нескольких методов в Java?

Но тогда это должно дать вам два кнопки для выбора из улыбки и нахмуренных кнопок, которые должны перерисовывать лица, чтобы показать, что один улыбается или хмурится, но по какой-то причине он не работает.

Я читал о графике, и я знаю, что вы не должны называть их из-за метода paint(), поэтому я изменил свой код соответственно, и я могу сказать, что кнопки работают, потому что я заставляю их распечатывать что-то каждый раз, но фактическая перерисовка не работает. Я попытался использовать repaint() и revalidate(). По какой-то причине, если вы используете repaint(), он все больше и больше перерисовывается каждый раз, когда это странно, но, возможно, это должно вести себя таким образом?

Может кто-нибудь, пожалуйста, взгляните на код и сообщите мне, что вы думаете о проблеме, или где я должен искать решение. Я использовал java некоторое время, но никогда не использую графику:/I have прочитайте, как предполагается, использовать setVisible/setSize (или pack()) в конце, и это действительно помогло с некоторыми проблемами, которые у меня были раньше, но я не понимаю, что делать, когда вы хотите сделать несколько вещей. В большинстве примеров только рисовать одну вещь ,

import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 

public class JSmileFacePanel2 extends JFrame { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

JButton smile = new JButton("SMILE"); 
JButton frown = new JButton("FROWN"); 

public JSmileFacePanel2() { 
    setLayout(new FlowLayout()); 
    setTitle("JSmileFace-V2: Jose M. Tobar"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    add(frown); 
    add(smile); 

    setSize(800, 800); 
    setVisible(true); 
} 

public void paint(Graphics g) { 
    super.paint(g); 
    //by default should show smiling 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 

    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      drawSmile(g); 

     } 
    }); 

    frown.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("FROWN BUTTON CLICKED"); 
      drawFrown(g); 
     } 
    }); 
} 

public void drawSmile(Graphics g) { 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 
    repaint(); 
} 

public void drawFrown(Graphics g) { 
    g.setColor(Color.WHITE); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 
    repaint(); 
} 


public static void main(String[] args) { 
    JSmileFacePanel2 js = new JSmileFacePanel2(); 
} 

} 

ответ

1

Вы все еще вызываете методы рисования вне метода paint, потому что методы actionPerformed отличаются от методов paint. Не имеет значения, что они текстовые внутри него, это по-прежнему другой метод.

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

Итак, проверьте, следует ли вам улыбаться или нахмуриться внутри метода paint и добавить слушателей действий внутри конструктора.

код становится:

import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 

public class JSmileFacePanel2 extends JFrame { 

    private static final long serialVersionUID = 1L; 

    // by default should show smiling 
    private boolean doSmile = true; 

    JButton smile = new JButton("SMILE"); 
    JButton frown = new JButton("FROWN"); 

    public JSmileFacePanel2() { 
     setLayout(new FlowLayout()); 
     setTitle("JSmileFace-V2: Jose M. Tobar"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     add(frown); 
     add(smile); 

     smile.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("SMILE BUTTON CLICKED"); 
       doSmile = true; 
       repaint(); 
      } 
     }); 

     frown.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("FROWN BUTTON CLICKED"); 
       doSmile = false; 
       repaint(); 
      } 
     }); 

     setSize(800, 800); 
     setVisible(true); 
    } 

    public void paint(final Graphics g) { 
     super.paint(g); 

     if (doSmile) { 
      drawSmile(g); 
     } else { 
      drawFrown(g); 
     } 
    } 

    public void drawSmile(Graphics g) { 
     g.setColor(Color.YELLOW); 
     g.fillOval(200, 200, 500, 500); 
     g.setColor(Color.BLUE); 
     g.fillOval(300, 360, 50, 50); 
     g.setColor(Color.BLUE); 
     g.fillOval(600, 360, 50, 50); 
     g.drawArc(400, 400, 100, 40, 180, 185); 
    } 

    public void drawFrown(Graphics g) { 
     g.setColor(Color.WHITE); 
     g.fillOval(200, 200, 500, 500); 
     g.setColor(Color.BLUE); 
     g.fillOval(300, 360, 50, 50); 
     g.setColor(Color.BLUE); 
     g.fillOval(600, 360, 50, 50); 
     g.drawArc(400, 400, 100, 40, 180, 185); 
    } 

    public static void main(String[] args) { 
     JSmileFacePanel2 js = new JSmileFacePanel2(); 
    } 

} 
0

главная проблема: вы добавляете много actionlisters в вашем коде ...

... всякий раз, когда repaint() называется, он вызывает внутренне метод paint(Graphics g) и внутри малярной метода вы» повторное добавление ActionListener (снова и снова и снова, каждый раз, когда вы перерисовки)

попробовать добавить ActionListener в конструкторе:

public JSmileFacePanel2() { 
    setLayout(new FlowLayout()); 
    setTitle("JSmileFace-V2: Jose M. Tobar"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    add(frown); 
    add(smile); 

    setSize(800, 800); 
    setVisible(true); 


    //here: 
    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      drawSmile(g); 

     } 
    }); 

    frown.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("FROWN BUTTON CLICKED"); 
      drawFrown(g); 
     } 
    }); 

} 
1

Одним словом, нет. Но, вы на правильном пути.

Помните, что вы работаете в среде, управляемой событиями, что означает, что что-то происходит, а затем вы отвечаете на него.

Картина не должны делать ничего больше, то просто окрасить текущее состояние, в вашем примере, каждый раз, когда paint называется, вы добавляете новый ActionListener к кнопкам, так что вы могли бы в конечном итоге с 3 + ActionListener с прикрепленными к каждому ваших кнопок, только когда экран становится видимым, что приведет к некоторому серьезному странному поведению.

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

Вы также должны избегать распространения из контейнеров верхнего уровня и переопределения paint (обычно), предпочитая вместо этого использовать JPanel и вместо этого вместо этого использовать метод paintComponent.

Две основные причины этого: во-первых, он блокирует вас в одном случае, что означает, что вы не можете повторно использовать свои компоненты, а во-вторых, рисовать непосредственно в контейнере верхнего уровня, например JFrame, вы можете рисовать под украшениями рамы/границы и из-за того, как работает живопись, даже имея надпись на ней кадров.

См Painting in AWT and Swing и Performing Custom Painting для получения более подробной информации

Общее решение использовать флаг, чтобы изменить способ, в котором ваши окрасочные работы процесса и изменить этот флаг, соответственно, если вы хотите (изнутри от кнопки ActionListener с для пример)

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
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.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class JSmileFace { 

    private static final long serialVersionUID = 1L; 

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

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

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new SmilyPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class SmilyPane extends JPanel { 

     JButton smile = new JButton("SMILE"); 
     JButton frown = new JButton("FROWN"); 

     private boolean frowning = false; 

     public SmilyPane() { 
      setLayout(new FlowLayout()); 

      add(frown); 
      add(smile); 

      smile.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        frowning = false; 
        repaint(); 
       } 
      }); 

      frown.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("FROWN BUTTON CLICKED"); 
        frowning = true; 
        repaint(); 
       } 
      }); 
     } 

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

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.YELLOW); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 

      if (frowning) { 
       drawFrown(g); 
      } else { 
       drawSmile(g); 
      } 
     } 

     public void drawSmile(Graphics g) { 
      g.setColor(Color.YELLOW); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 
     } 

     public void drawFrown(Graphics g) { 
      g.setColor(Color.WHITE); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 
     } 

    } 

} 
0

небольшой недостаток: не называют drawFrown(g) или drawSmile(g) внутри вашего actionListener (вы не можете больше, вы не знаете graphics больше) вместо того, чтобы позвонить repaint().

Но прежде чем repaint() вы говорите ваш графический , что будет нарисован (я использую int для этого лучше использовать Enums, но он будет работать прямо сейчас

я просто делаю smile- часть, нахмурившись часть такая же

private int style = 0; 

public JSmileFacePanel2() { 

    //other code as above 
    ... 

    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      style = 1; //1=smile, 2=frown 
      repaint(); //this calls internally the paint(g) method 
     } 
    }); 
} 

и настроить ваш метод краски:

public void paint(Graphics g) { 
    super.paint(g); 
    //by default should show smiling 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 

    if(style == 1){ 
     drawSmile(g); 
    } 

    if(style == 2){ 
     drawFrown(g); 
    } 
} 
Смежные вопросы