This discussion is archived
0 Replies Latest reply: Jan 26, 2010 8:17 AM by 807559 RSS

Popup or JDialog for complex objects

807559 Newbie
Currently Being Moderated
Hello all, I'm developing this small JAgenda based on JCalendar by Kai Tödter (http://www.toedter.com/en/contact.html).

This is my idea for showing a modal popup window to magnify the single AgendaDayObject (in place of the simple jbutton in JCalendar) in the center of the screen:
         public class AgendaDayObject extends JPanel {

          private int day;
          private JLabel label;
          private JList list;
          private JButton magnifier;
          private int magnifierSize = 16;
          
          public AgendaDayObject() {
          }
          
          public AgendaDayObject(int day) {

               this.day = day;
               this.setLayout(new GridLayout(1,1));
               
               
               //LABEL PANEL
               label = new JLabel();
               if (day != 0) label.setText(String.valueOf(day));
               label.setForeground(dayForegroundColor);
                    
               label.setHorizontalAlignment(SwingConstants.CENTER);
               label.setVerticalAlignment(SwingConstants.CENTER);
               label.setOpaque(false);
               
               //JLIST
               list = new JList();
               list.setModel(new DefaultListModel());
               list.setBorder(BorderFactory.createLineBorder(Color.GRAY));
               //JScrollPane scroll = new JScrollPane(list);
               
               //MAGNIFIER
               magnifier = new JButton();
               magnifier.setIcon(new ImageIcon("rsc/icons/zoom_r_button.png"));
               magnifier.setOpaque(false);
               magnifier.setBorderPainted(false);
               magnifier.setFocusPainted(false);
               magnifier.setContentAreaFilled(false);
               magnifier.addActionListener(new MagnifierListener());
                                                       
               //LAYER FOR OVERLAPPING
               FilledLayeredPane layers = new FilledLayeredPane();
               layers.add(label, JLayeredPane.PALETTE_LAYER);
               layers.add(list, JLayeredPane.DEFAULT_LAYER);
               layers.add(magnifier, JLayeredPane.POPUP_LAYER);
               
               this.add(layers);
                    
          }

          public int getDay() {
               return day;
          }

          public void setDay(int day) {
               this.day = day;
               label.setText(String.valueOf(day));
          }

          public JList getList() {
               return list;
          }

          public void setList(JList list) {
               this.list = list;
          }
          
          public JLabel getLabel() {
               return label;
          }

          private class FilledLayeredPane extends JLayeredPane {
              /**
               * Layout each of the components in this JLayeredPane so that they all fill
               * the entire extents of the layered pane -- from (0,0) to (getWidth(), getHeight())
               */
              public void doLayout() {
                  // Synchronizing on getTreeLock, because I see other layouts doing that.
                  // see BorderLayout::layoutContainer(Container)
                  synchronized(getTreeLock()) {
                      int w = getWidth();
                      int h = getHeight();
                      for(Component c : getComponents()) {
                           c.setBounds(0, 0, w, h);
                           if (c instanceof JLabel) {
                               c.setFont(new Font("Serif", Font.PLAIN, (int) (h*0.8)));
                          }
                           if (c instanceof JButton) {
                                c.setBounds(w-magnifierSize-5, h-magnifierSize-5, magnifierSize, magnifierSize);
                           }
                           
                      }
                  }
              }
          }
          
          @Override
          public void setVisible(boolean flag) {
               this.label.setVisible(flag);
               this.list.setVisible(flag);
               this.magnifier.setVisible(flag);
               this.setBorder(null);
          }
          
          public class MagnifierListener implements ActionListener {

               public void actionPerformed(ActionEvent e) {
                    
                    int day = AgendaDayObject.this.day;
                    JPanel thisDay = null;
                    thisDay = AgendaDayObject.this.popUp();
                    final JDialog dialog = new JDialog();
                    dialog.add(thisDay);
                    dialog.setUndecorated(true);
                    dialog.setSize(new Dimension(600,400));
                    dialog.setLocationRelativeTo(null);
                    dialog.setVisible(true);
                    dialog.setFocusable(true);
                    dialog.addFocusListener(new FocusListener() {

                         public void focusGained(FocusEvent e) {
                              // TODO Auto-generated method stub
                              
                         }

                         public void focusLost(FocusEvent e) {
                              dialog.setVisible(false);
                         }
                    });
               }
          }
          
          private JPanel popUp() {
               
               //A NEW PANEL
               JPanel copyPanel = new JPanel();
               copyPanel.setLayout(new GridLayout(1,1));
               JLabel label = new JLabel(this.label.getText());
               
               //LABEL
               label.setHorizontalAlignment(SwingConstants.CENTER);
               label.setVerticalAlignment(SwingConstants.CENTER);
               label.setOpaque(false);
               label.setForeground(dayForegroundColor);
               
               //LIST WITH SCROLL
               JList list = new JList(this.list.getModel());
               JScrollPane scroll = new JScrollPane(list);
               
               FilledLayeredPane layers = new FilledLayeredPane();
               layers.add(label, JLayeredPane.PALETTE_LAYER);
               layers.add(scroll, JLayeredPane.DEFAULT_LAYER);
               copyPanel.add(layers);
               
               return copyPanel;
          }
     }
I wrote a popUp() method that basically re-create the Panel with desired content; this one is shown in a JDialog that auto-close itself on focus lost event. JPopMenu was not working fine as well as clone() method (some errors about layout management) but I'm not a master about them so sure there is a more simple and linear way to do it!

Any suggestion and/or complaints... :p are both almost welcome!
Thanks

Edited by: mwiti on Jan 26, 2010 8:16 AM