动态更换一组按钮

时间:2017-12-18 11:56:43

标签: java swing

这是我在java Swing中的第一次试用。我遇到的问题是每次月份更改时都会重新创建日历面板。我想在调用addMonth时重新填充panelRightDown(当点击>或<时)。我试过在addMonth中调用revalidate,invalidate,repaint但是一切都变得乱七八糟。计算年份时应该采用相同的方法。任何帮助,将不胜感激。更重要的是,我们非常欢迎更好的方法。

public class Gui extends JFrame {   
    private final int windowWidth = 700;
    private final int windowHeight = 600;
    private final Container container;
    private final JPanel panelLeft = new JPanel();
    private final JPanel panelRight = new JPanel();
    private final GridBagConstraints gridBagConstraints = new GridBagConstraints();
    private final int verticalSpacerSize = 8;
    private final int horizontalSpacerSize = 15;
    private Border lowerEtchedBorder = 
            BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);

    // -----
    protected boolean controlsOnTop;
    protected boolean removeOnDaySelection;

    protected Calendar currentDisplayDate;

    protected JButton prevMonth;
    protected JButton nextMonth;
    protected JButton prevYear;
    protected JButton nextYear;

    protected JTextField textField;

    protected List<ActionListener> popupListeners = 
        new ArrayList<ActionListener>();

    protected Popup popup;

    protected SimpleDateFormat dayName   = new SimpleDateFormat("d");
    protected SimpleDateFormat monthName = new SimpleDateFormat("MMMM");

    protected String iconFile = "datepicker.gif";
    protected String[] weekdayNames = 
        {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    JPanel datePanel = new JPanel();
    JPanel panelRightDown = new JPanel();
    JPanel controlsPanel;
    // -----

    // Constructor to setup the GUI components and event handlers
    public Gui() {
        //-----
        currentDisplayDate   = Calendar.getInstance();
        controlsOnTop        = true;
        removeOnDaySelection = true;
        //createPanel();

        // Retrieve the content-pane of the top-level container JFrame
        // All operations done on the content-pane

        container = getContentPane();
        container.setLayout(new BorderLayout());
        //container.setMinimumSize(new Dimension(windowWidth, windowHeight));
        createMenuBar();
        createStatusBar();

        JPanel fullPane = new JPanel();
        fullPane.setLayout(new GridBagLayout());
        // Spacer
        container.add(Box.createVerticalStrut(
                4), BorderLayout.NORTH);
        container.add(fullPane, BorderLayout.CENTER);
        fullPane.setMinimumSize(new Dimension(windowWidth, windowHeight));

        // Position Left and Right panels
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.weightx = 0.3;
        gridBagConstraints.weighty = 1.0;
        fullPane.add(panelLeft, gridBagConstraints);

        gridBagConstraints.gridx = 1;
        gridBagConstraints.weightx = 0;
        fullPane.add(Box.createHorizontalStrut(
                15), gridBagConstraints);

        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 2;
        gridBagConstraints.weightx = 0.9;
        fullPane.add(panelRight, gridBagConstraints);


        configurePanelLeft(panelLeft);
        configurePanelRight(panelRight);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Prod - Reminder"); 
        setSize(windowWidth, windowHeight);
        setLocationRelativeTo(null);
        setVisible(true);
        addWindowListener(new Terminator());
    }

    public void setDate(String date) {
        currentDisplayDate = Calendar.getInstance();
        editDate(date);
    }

    public void setDate(Calendar date) {
        currentDisplayDate = date;
        //createPanel();
        validate();
        repaint();
    }

    public void setDate(int month, int day, int year) {
        currentDisplayDate = Calendar.getInstance();
        currentDisplayDate.set(expandYear(year), month - 1, day);
        //createPanel();
        validate();
        repaint();
    }

    protected int expandYear(int year) {
        if (year < 100) {                   // 2 digit year
            int currentYear = Calendar.getInstance().get(Calendar.YEAR);
            int current2DigitYear = currentYear % 100;
            int currentCentury    = currentYear / 100 * 100;
            // set 2 digit year range +20 / -80 from current year
            int high2DigitYear    = (current2DigitYear + 20) % 100;
            if (year <= high2DigitYear) {
                year += currentCentury;
            }
            else {
                year += (currentCentury - 100);
            }
        }
        return year;
    }

    public void setControlsOnTop(boolean flag) {
        controlsOnTop = flag; 
        //createPanel();
        repaint();
    }

    public Calendar getCalendarDate() {
        return currentDisplayDate;
    }

    public Date getDate() {
        return currentDisplayDate.getTime();
    }

    public String getFormattedDate() {
        return Integer.toString(getMonth()) + "/" + 
            Integer.toString(getDay()) + "/" +
            Integer.toString(getYear());
    }

    public int getMonth() {
        return currentDisplayDate.get(Calendar.MONTH) + 1;
    }

    public int getDay() {
        return currentDisplayDate.get(Calendar.DAY_OF_MONTH);
    }

    public int getYear() {
        return currentDisplayDate.get(Calendar.YEAR);
    }

    protected JPanel createControls() {        
        JPanel c = new JPanel();
        c.setBorder(BorderFactory.createRaisedBevelBorder());
        c.setFocusable(true);
        c.setLayout(new FlowLayout(FlowLayout.CENTER));

        prevYear = new JButton("<<");
        c.add(prevYear);
        prevYear.setMargin(new Insets(0,0,0,0));
        prevYear.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                addYear(-1);        
            }
        });

        prevMonth = new JButton("<");
        c.add(prevMonth);
        prevMonth.setMargin(new Insets(0,0,0,0));
        prevMonth.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                addMonth(-1);       
            }
        });


        textField = new JTextField(getFormattedDate(), 10);
        c.add(textField);
        textField.setEditable(true);
        textField.setEnabled(true);
        textField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                editDate(textField.getText());
            }
        });


        nextMonth = new JButton(">");
        c.add(nextMonth);
        nextMonth.setMargin(new Insets(0,0,0,0));
        nextMonth.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                addMonth(+1);   
            }
        });

        nextYear = new JButton(">>");
        c.add(nextYear);
        nextYear.setMargin(new Insets(0,0,0,0));
        nextYear.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                addYear(+1);    
            }
        });

        return c;
    }

    protected JPanel configureDatePicker() {
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c  = new GridBagConstraints();

        datePanel.setFocusable(true);
        datePanel.setLayout(gridbag);

        String month = monthName.format(currentDisplayDate.getTime());
        String year  = Integer.toString(getYear());

        c.gridx      = 0;
        c.gridy      = 0;
        c.gridwidth  = 7;
        c.gridheight = 1;
        JLabel title = new JLabel(month + " " + year);
        datePanel.add(title, c);
        Font font      = title.getFont();
//        Font titleFont = new Font(font.getName(), font.getStyle(),
//              font.getSize() + 2);
        Font weekFont = new Font(font.getName(), font.getStyle(),
                font.getSize() - 2);
        title.setFont(font);

        c.gridy      = 1;
        c.weightx    = 0.1;
        c.weighty    = 0.1;
        c.gridwidth  = 1;
        c.gridheight = 1;
        c.fill = GridBagConstraints.BOTH;
        for (c.gridx = 0; c.gridx < 7; c.gridx++) {
            JLabel label = new JLabel(
                    weekdayNames[c.gridx], SwingConstants.CENTER);
            datePanel.add(label, c);
            label.setFont(weekFont);
        }

        Calendar draw = (Calendar) currentDisplayDate.clone();
        draw.set(Calendar.DATE, 1);
        draw.add(Calendar.DATE, -draw.get(Calendar.DAY_OF_WEEK) + 1);
        int monthInt = currentDisplayDate.get(Calendar.MONTH);
//      monthInt = 0;
//      System.out.println("Current month: " + monthInt);

        c.gridwidth  = 1;
        c.gridheight = 1;
        int width    = getFontMetrics(weekFont).stringWidth(" Wed ");
        int width1   = getFontMetrics(weekFont).stringWidth("Wed");
        int height   = getFontMetrics(weekFont).getHeight() + 
                (width - width1);

        for (c.gridy = 2; c.gridy < 8; c.gridy++) {
            for (c.gridx = 0; c.gridx < 7; c.gridx++) {
                JButton dayButton;
//              System.out.print("Draw month: " + draw.get(Calendar.MONTH));
                if (draw.get(Calendar.MONTH) == monthInt) {
                    String dayString = dayName.format(draw.getTime());
                    if (draw.get(Calendar.DAY_OF_MONTH) < 10) {
                        dayString = " " + dayString;
                    }

                    dayButton = new JButton(dayString);
                } else {
                    dayButton = new JButton();
                    dayButton.setEnabled(false);
                }
//              System.out.println(", day: " + dayName.format(draw.getTime()));
                datePanel.add(dayButton, c);
                Color color = dayButton.getBackground();
                if ((draw.get(Calendar.DAY_OF_MONTH) == getDay()) &&
                        (draw.get(Calendar.MONTH) == monthInt)) { 
                    dayButton.setBackground(Color.yellow);
//                  dayButton.setFocusPainted(true);
//                  dayButton.setSelected(true);
                } else
                    dayButton.setBackground(color);
                dayButton.setFont(weekFont);
                dayButton.setFocusable(true);
                //dayButton.setPreferredSize(new Dimension(width, height));
                //dayButton.setMargin(new Insets(0,0,0,0));
                dayButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        changeDay(e.getActionCommand());
                    }

                });
                //if (dateChange != null)
                //    dayButton.addActionListener(dateChange);
                draw.add(Calendar.DATE, +1);
            }
//          if (draw.get(Calendar.MONTH) != monthInt) break;
        }
        return datePanel;
    }

    public void addMonth(int month) {
        currentDisplayDate.add(Calendar.MONTH, month);
        datePanel.invalidate();
        controlsPanel.invalidate();
        panelRightDown.validate();

        datePanel = configureDatePicker();
        controlsPanel = createControls();

        panelRightDown.removeAll();
        panelRightDown.add(controlsPanel);
        panelRightDown.add(datePanel);
        validate();
        repaint();
    }

    public void addYear(int year) {
        currentDisplayDate.add(Calendar.YEAR, year);

        validate();
        repaint();
    }

    public void editDate(String date) {
        parseDate(date);
        //createPanel();
        validate();
        repaint();
    }

    protected void parseDate(String date) {
        String[] parts = date.split("/");
        switch (parts.length) {
            case 3:
                currentDisplayDate.set(Calendar.MONTH,
                        Integer.valueOf(parts[0]) - 1);
                currentDisplayDate.set(Calendar.DAY_OF_MONTH,
                        Integer.valueOf(parts[1]));
                currentDisplayDate.set(Calendar.YEAR,
                        expandYear(Integer.valueOf(parts[2])));
                break;
            case 2:
                currentDisplayDate = Calendar.getInstance();
                currentDisplayDate.set(Calendar.MONTH,
                        Integer.valueOf(parts[0]) - 1);
                currentDisplayDate.set(Calendar.DAY_OF_MONTH,
                        Integer.valueOf(parts[1]));
                break;
            default:
                // invalid date
                currentDisplayDate = Calendar.getInstance();
                break;
        }
    }

    public void changeDay(String day) {
        currentDisplayDate.set(Calendar.DAY_OF_MONTH, 
                Integer.valueOf(day.trim()));
        textField.setText(getFormattedDate());
        if (!removeOnDaySelection) {
            //createPanel();
            //validate();
            repaint();
        }
    }

    private void createMenuBar() {
        JMenuBar menubar = new JMenuBar();

        JMenu file = new JMenu("File");
        file.setMnemonic(KeyEvent.VK_F);

        JMenuItem eMenuItem = new JMenuItem("Exit");
        eMenuItem.setMnemonic(KeyEvent.VK_E);
        eMenuItem.setToolTipText("Exit application");
        eMenuItem.addActionListener((ActionEvent event) -> {
            System.exit(0);
        });

        file.add(eMenuItem);

        menubar.add(file);

        setJMenuBar(menubar);
    }

    private void createStatusBar() {
        // create the status bar panel and shove it down the bottom of the frame
        JPanel statusPanel = new JPanel();
        statusPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
        container.add(statusPanel, BorderLayout.SOUTH);
        statusPanel.setPreferredSize(new Dimension(container.getWidth(), 20));
        statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
        JLabel statusLabel = new JLabel("status");
        statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
        statusPanel.add(statusLabel);
    }

    public void configurePanelLeft(JPanel panel) {
        // Configure Left-side panels
        // Top panel
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.weightx = 0.3;
        gridBagConstraints.weighty = 0.3;
        JPanel panelLeftTop = new JPanel();
        panelLeftTop.setBorder(
                BorderFactory.createMatteBorder(1, 1, 1, 1, Color.YELLOW));

        panel.setLayout(new GridBagLayout());
        panel.add(panelLeftTop, gridBagConstraints);

        // Display Area
        JTextArea displayItem = new JTextArea("Hello, left top!");
        displayItem.setBorder(lowerEtchedBorder);
        displayItem.setLineWrap(true);
        displayItem.setBackground(panel.getBackground());
        displayItem.setWrapStyleWord(true);
        //displayItem.setEditable(false);
        panelLeftTop.setLayout(new BorderLayout());

        JScrollPane topScrollPane = new JScrollPane();
        topScrollPane.getVerticalScrollBar().setUnitIncrement(3);
        topScrollPane.setViewportView(displayItem);
        topScrollPane.setHorizontalScrollBarPolicy(
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        panelLeftTop.add(topScrollPane);

        // Spacer
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0;
        panel.add(Box.createVerticalStrut(
                verticalSpacerSize), gridBagConstraints);

        // Bottom panel
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.7;
        JPanel panelLeftDown = new JPanel();
        panelLeftDown.setBorder(
                BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLUE));
        panelLeftDown.setLayout(new GridBagLayout());

        for (int i = 0; i < 50; i++) {
            gridBagConstraints.fill = GridBagConstraints.BOTH;
            gridBagConstraints.gridx = 0;
            gridBagConstraints.gridy = i;
            gridBagConstraints.weightx = 0.3;
            //gridBagConstraints.weighty = 1.0;
            String textValue = "Area: "+ i 
                    +" This is a very long wrapped text, "
                    + "which I expect to be an example of text in a label. "
                    + "I really hope it works well."
                    + "The Scroll Bar comes when your text goes beyond "
                    + "the bounds of your view area. "
                    + "Don't use Absolute Positioning, for such a small "
                    + "talk at hand, always prefer Layout Managers, "
                    + "do read the first para of the first link, "
                    + "to know the advantage of using a Layout Manager.";
            JTextArea textArea = new JTextArea(textValue);
            textArea.setBorder(lowerEtchedBorder);
            textArea.setLineWrap(true);
            textArea.setBackground(panel.getBackground());
            textArea.setWrapStyleWord(true);
            textArea.setEditable(false);
            textArea.addMouseListener(new MouseListener() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    displayItem.setText(textValue);
                    javax.swing.SwingUtilities.invokeLater(new Runnable() {
                        public void run() { 
                            topScrollPane.getVerticalScrollBar().setValue(0);
                        }
                    });
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }
            });
            panelLeftDown.add(textArea, gridBagConstraints);
        }

        JScrollPane scrollPane = new JScrollPane(panelLeftDown,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        panelLeftDown.setAutoscrolls(true);
        scrollPane.setPreferredSize(new Dimension(300,800));
        scrollPane.getVerticalScrollBar().setUnitIncrement(3);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() { 
                scrollPane.getVerticalScrollBar().setValue(0);
            }
         });
        panel.add(scrollPane, gridBagConstraints);

    }

    public void configurePanelRight(JPanel panel) {
        // Configure right-side panels   
        // Top panel
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.1;
        JPanel panelRightTop = new JPanel();
        panelRightTop.setBorder(
                BorderFactory.createMatteBorder(1, 1, 1, 1, Color.YELLOW));
        panelRightTop.add(new JLabel("Hello, right top!"));
        panel.setLayout(new GridBagLayout());
        panel.add(panelRightTop, gridBagConstraints);

        // Spacer
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0;
        panel.add(Box.createVerticalStrut(
                verticalSpacerSize), gridBagConstraints);

        // Bottom panel
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.9;

        panelRightDown.setBorder(
                BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLUE));
        //panelRightDown.add(new JLabel("Hello, right down!"));
        panel.add(panelRightDown, gridBagConstraints);
        panel.add(panelRightDown, gridBagConstraints);

        // Date Picker
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.1;
        panelRightDown.setLayout(new BorderLayout());
        datePanel = configureDatePicker();
        controlsPanel = createControls();
        panelRightDown.add(controlsPanel, BorderLayout.NORTH);
        panelRightDown.add(datePanel, BorderLayout.CENTER);
    }

    private ListCellRenderer<? super String> getRenderer() {
        return new DefaultListCellRenderer(){
            @Override
            public Component getListCellRendererComponent(JList<?> list,
                    Object value, int index, boolean isSelected,
                    boolean cellHasFocus) {
                JLabel listCellRendererComponent = 
                        (JLabel) super.getListCellRendererComponent(
                                list, value, index, isSelected,cellHasFocus);
                listCellRendererComponent.setBorder(
                        lowerEtchedBorder);
                listCellRendererComponent.setEnabled(true);
                return listCellRendererComponent;
            }
        };
    }

    public static void main(String[] args) {
        // Run the GUI construction in the Event-Dispatching thread for thread-safety
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Gui(); // Let the constructor do the job
            }
        });
    }

}

0 个答案:

没有答案