2012-12-23 18 views
5

मैं एक छोटा जीयूआई बनाने की कोशिश कर रहा हूं, इसमें 2 जेबूटन और 2 जेपीनेल हैं जिनमें से प्रत्येक पर कुछ ड्राइंग एनीमेशन है। डिफ़ॉल्ट रूप से इसे पहले जेपीनल दिखाना चाहिए, और दूसरे जेबटन पर क्लिक करके मैं अपना दूसरा जेपीनल देखना चाहता हूं। तो: मैं जेफ्रेम, पैनल 1 और पैनल 2 बना रहा हूं, जहां मैंने अपने एनिमेशन खींचे हैं, बटन 1 और बटन 2 बनाये हैं और उन्हें एक्शनलिस्टनर जोड़ रहे हैं। मेरे पास मेनपैनल भी है जो फ़ील्ड वैरिएबल में है। इसे "i" बदलकर मेरा कन्स्ट्रक्टर मेनपैनल को पैनल 1 (डिफ़ॉल्ट) या पैनल 2 में जोड़ता है (जेबटन 2 पर क्लिक करके मैं बदलता हूं)। मैं इस मेनपैनल को अपने फ्रेम में जोड़ता हूं। तो मेरा सवाल: क्लास मेनपैनल में मैंने रीफ्रेश किया है मेरी विधि, मुझे अपना जीयूआई सही तरीके से काम करने के लिए क्या लिखना चाहिए? धन्यवाद।जेबटन पर क्लिक करके जेपीनल कैसे जोड़ें?

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

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

public class GuiTest { 

    public static void main(String[] args) { 
     JFrame f = new JFrame(); 
     MainPanel myPanel = new MainPanel(); 
     f.add(myPanel); 
     Button1 button1 = new Button1(); 
     Button2 button2 = new Button2(); 
     myPanel.add(button1); 
     myPanel.add(button2); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.pack(); 
     f.setVisible(true); 
    } 
} 

class MainPanel extends JPanel { 
    Panel1 p1 = new Panel1(); 
    Panel2 p2 = new Panel2(); 
    public int i = 1; //this is being changed later by clicking JButton 
    // I use this setter later in actionPerformed in order to change i 
    public void setI(int i) { 
     this.i = i; 
    } 

    MainPanel() { 
     if (i == 1) { 
      this.add(p1); 
     } 
     if (i == 2) { 
      this.add(p2); 
     } 
    } 

    public void refreshMe() { 
     // Need some help here: 
     // I don't know what should I write, how to make a repaint of myPanel? 
     System.out.println("just test, if the method refreshMe working by clicking some button"); 
    } 
} 

class Panel1 extends JPanel { 

    public Panel1() { 
     this.setBackground(Color.BLUE); 
     // a lot of drawing stuff going on here 
    } 

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

class Panel2 extends JPanel { 

    public Panel2() { 
     this.setBackground(Color.GREEN); 
     // a lot of drawing stuff going on here 
    } 

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

} 

class Button1 extends JButton { 
    MainPanel someObj1 = new MainPanel(); 

    Button1() { 
     setText("Show Annimation A"); 
     addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       someObj1.setI(1); 
       System.out.println("The variable i is now: " + someObj1.i); 
       someObj1.refreshMe(); 

      } 
     }); 
    } 

} 

class Button2 extends JButton { 
    MainPanel someObj2 = new MainPanel(); 

    Button2() { 
     setText("Show Annimation B"); 
     addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       someObj2.setI(2); 
       System.out.println("The variable i is now: " + someObj2.i); 
       someObj2.refreshMe(); 
      } 
     }); 

    } 

} 

उत्तर

8

को देखें आदेश जोड़ने/निकालने या घटक एक दृश्य कंटेनर कॉल revalidate() और repaint() कंटेनर उदाहरण पर जोड़ने/हटाने के या घटक आकार बदलने के बाद पर है कि आकार बदलने के बाद बदलाव को प्रतिबिंबित करने के लिए।

इस हालांकि JButton कक्षाओं के अंदर जा रहा है अपने कोड में काम नहीं करेगा मुख्य कारण आप MainPanel का एक नया उदाहरण पुन: जब वास्तव में 2 JButtons एक उदाहरण है जो किया जा रहा है साझा करना चाहिए (आप JButton को MainPanel उदाहरण दे सकते हैं रों कंस्ट्रक्टर्स, लेकिन तुम सच में नहीं विस्तार किया जाना चाहिए एक JButton कस्टम कार्यक्षमता) जोड़ने जब तक:

class Button2 extends JButton { 
    MainPanel someObj2 = new MainPanel();//you create an instance of MainPanel which isnt even showing and than do changes on that, this way you will never see any of the changes 

    Button2() { 
    } 
} 

एक अपने कोड पर कुछ अन्य सुझाव:

  • JButton कक्षा को अनावश्यक रूप से विस्तारित न करें, बस JButton का उदाहरण बनाएं जैसे आपने JFrame के साथ किया था और JButton उदाहरण पर कॉल विधियों को कॉल किया था।

  • न बनाने के लिए/Event Dispatch Thread पर घुमाओ घटकों में हेरफेर, SwingUtilities.invokeLater(..) ब्लॉक के माध्यम से भूल जाते हैं, और अधिक के लिए here पढ़ें।

अपने कोड तय हो गई है (ऊपर दिए गए सुझाव ect कार्यान्वित):

1) CardLayout का प्रयोग करें जो आप की अनुमति देगा:

import java.awt.Color; 
import java.awt.Dimension; 
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.SwingUtilities; 

public class Test { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame f = new JFrame(); 

       final MainPanel myPanel = new MainPanel(); 
       f.add(myPanel); 

       JButton button1 = new JButton("Show Animation A"); 
       JButton button2 = new JButton("Show Animation B"); 

       button1.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         myPanel.setI(1); 
         System.out.println("The variable i is now: " + myPanel.i); 
         myPanel.refreshMe(); 
        } 
       }); 
       button2.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         myPanel.setI(2); 
         System.out.println("The variable i is now: " + myPanel.i); 
         myPanel.refreshMe(); 
        } 
       }); 

       myPanel.add(button1); 
       myPanel.add(button2); 
       myPanel.checkPanel(); 

       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 

class MainPanel extends JPanel { 

    Panel1 p1 = new Panel1(); 
    Panel2 p2 = new Panel2(); 
    public int i = 1; //this is being changed later by clicking JButton 
    // I use this setter later in actionPerformed in order to change i 

    public void setI(int i) { 
     this.i = i; 
    } 

    public void refreshMe() { 
     checkPanel(); 

     revalidate(); 
     repaint(); 
     // Need some help here: 
     // I don't know what should I write, how to make a repaint of myPanel? 
     System.out.println("just test, if the method refreshMe working by clicking some button"); 
    } 

    public void checkPanel() { 
     if (i == 1) { 
      this.add(p1); 
      this.remove(p2);//or it will remain there as this is default flowlayout 
     } else if (i == 2) { 
      this.add(p2); 
      this.remove(p1); 
     } 
    } 
} 

class Panel1 extends JPanel { 

    public Panel1() { 
     this.setBackground(Color.BLUE); 
     // a lot of drawing stuff going on here 
    } 

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

class Panel2 extends JPanel { 

    public Panel2() { 
     this.setBackground(Color.GREEN); 
     // a lot of drawing stuff going on here 
    } 

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

हालांकि ईद कुछ सरल सुझाव है, सौभाग्य से आप 2 विकल्प हैं एक एकल JFrame/कंटेनर पर एकाधिक घटकों के बीच फ़्लिप करने के लिए।

यहाँ एक उदाहरण मैंने बनाया है:

enter image description here

import java.awt.BorderLayout; 
import java.awt.CardLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class Test { 

    private final static String PANEL1 = "panel 1"; 
    private final static String PANEL2 = "panel 2"; 

    public Test() { 
     initComponents(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test(); 
      } 
     }); 
    } 

    private void initComponents() { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel panel1 = new JPanel(); 
     panel1.add(new JLabel("Panel 1")); 

     JPanel panel2 = new JPanel(); 
     panel2.add(new JLabel("Panel 2")); 

     //Create the panel that contains the "cards". 
     final JPanel cards = new JPanel(new CardLayout()); 
     cards.add(panel1, PANEL1); 
     cards.add(panel2, PANEL2); 

     //create button to allow chnage to next card 
     JButton buttonNext = new JButton(">"); 
     buttonNext.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       CardLayout cl = (CardLayout) (cards.getLayout());//get cards 
       cl.next(cards); 
      } 
     }); 

     //create button to allow chnage to previous card 
     JButton buttonPrev = new JButton("<"); 
     buttonPrev.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       CardLayout cl = (CardLayout) (cards.getLayout());//get cards 
       cl.previous(cards); 
      } 
     }); 

     //create panel to hold buttons which will allow switching between cards 
     JPanel buttonPanel = new JPanel(); 
     buttonPanel.add(buttonPrev); 
     buttonPanel.add(buttonNext); 


     frame.add(cards); 
     frame.add(buttonPanel, BorderLayout.SOUTH); 

     frame.pack(); 
     frame.setVisible(true); 
    } 
} 

2) removeAll() तकनीक यानी कॉल frame.getContentPane().removeAll() का प्रयोग करें JFrame पर वर्तमान में सभी घटकों को निकाल देंगे और की तुलना में नई सामग्री जोड़ सकते हैं और फोन जो revalidate() और repaint() (वहां pack() भी जोड़ना चाह सकता है) JFrame उदाहरण पर परिवर्तनों को प्रतिबिंबित करने के लिए। हालांकि आईडी CardLayout की सलाह देते हैं।

+0

मेरे कोड और उदाहरण को सही करने के लिए धन्यवाद, इससे बहुत मदद मिलती है! हां, कार्डलाउट मेरी समस्या हल करता है। – user1924939

3

मुझे लगता है कि तुम सिर्फ CardLayout का उपयोग अपने कार्य को लागू करने के कर सकते हैं: यहाँ मेरी कोड है। here

संबंधित मुद्दे