簡體   English   中英

我可以用 JButton 的名稱做一個 for 語句嗎?

[英]Can I make a for statement with the names of JButtons?

我正在為 NetBeans 中僅一年的日歷編程,對於 GUI,我計划將典型的日歷作為當年的微調器。 這種組合將決定該月的第一天和最后一天在一周中的哪一天。

我編寫的代碼存在的問題是使用日歷日按鈕的名稱作為變量。 也許有辦法為 NetBeans 准備一個聲明作為按鈕名稱?

對於這個日歷,我制作了一個帶有 49 個按鈕的 JPanel(有 7 行星期,這是日歷的最大值)。 我試圖將每個按鈕命名為“N(數字)”(數字從 1 到 49)。 這樣我就可以為 function 制作一個,這樣一個月的最后一天之后的第二天的 position 將是下個月第一天的 position。

JPanel 的圖像

此代碼將從 2022 年 1 月開始(不計算閏年)。 日歷的年份必須在“YearC”變量中指定(在他的例子中是 2022 年)。 還必須指定的另一個值是“FirstD”變量中一年的第一天之前日歷中空 position 的數量(在 2022 年 1 月的情況下為 5)。 最后,我對月份使用了微調器,因為用戶必須連續選擇月份才能使代碼正常工作。

代碼如下:

    public void WeekPos(){
        String MonIntCal = MonthCal.getValue().toString();
        int DayN = 0;
        int jub = 0;
        int DayC = 0;
        int FirstD = 6;
        String YearC = "2022";
        YearCal.setText(YearC);
        String Nam = "B"+DayC;
        int LastJan = 0;
        int LastFeb = 0;
        int LastMar = 0;
        int LastApr = 0;
        int LastMay = 0;
        int LastJun = 0;
        int LastJul = 0;
        int LastAug = 0;
        int LastSep = 0;
        int LastOct = 0;
        int LastNov = 0;
        
        switch(MonIntCal){
            case "January": DayN = 31; jub = 1;
            case "February": DayN = 28; jub = 2;
            case "March": DayN = 31; jub = 3;
            case "April": DayN = 30; jub = 4;
            case "May": DayN = 31; jub = 5;
            case "June": DayN = 30; jub = 6;
            case "July": DayN = 31; jub = 7;
            case "August": DayN = 31; jub = 8;
            case "September": DayN = 30; jub = 9;
            case "October": DayN = 31; jub = 10;
            case "November": DayN = 30; jub = 11;
            case "December": DayN = 31; jub = 12;
        }
        switch(jub){
            case 1: for (int i = 1; i<FirstD; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>DayN+FirstD; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN; i=i+1){
                         DayC = 5+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                    }
                    LastJan = DayN+5;
            case 2: for (int i = 1; i<LastJan; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastJan; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastJan+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastFeb = DayC;
                        }    
                    };
            case 3: for (int i = 1; i<LastFeb; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastFeb; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastFeb+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastMar = DayC;
                        }    
                    };
            case 4: for (int i = 1; i<LastMar; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastMar; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastMar+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastApr = DayC;
                        }    
                    };
            case 5: for (int i = 1; i<LastApr; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastApr; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastApr+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastMay = DayC;
                        }    
                    };
            case 6: for (int i = 1; i<LastMay; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastMay; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastMay+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastJun = DayC;
                        }    
                    };
            case 7: for (int i = 1; i<LastJun; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastJun; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastJun+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastJul = DayC;
                        }    
                    };
            case 8: for (int i = 1; i<LastJul; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastJul; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastJul+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastAug = DayC;
                        }    
                    };
            case 9: for (int i = 1; i<LastAug; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastAug; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastAug+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastSep = DayC;
                        }    
                    };
            case 10: for (int i = 1; i<LastSep; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastSep; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastSep+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastOct = DayC;
                        }    
                    };
            case 11: for (int i = 1; i<LastOct; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastOct; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastOct+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                        if(i==DayN){
                            LastNov = DayC;
                        }    
                    };
            case 12: for (int i = 1; i<LastNov; i=i+1){
                        DayC = i;
                        Nam.setText(null);  
                    }
                    for (int i = 49; i>LastNov; i=i-1){
                        DayC = i;
                        Nam.setText(null);
                    }
                    for (int i = 0; i<DayN+1; i=i){
                        DayC = LastNov+i;
                        if(DayC>49){
                         DayC=DayC-49;   
                        }
                        Nam.setText(i.toString());
                    };    
        }        
    }

因此,據我了解,您的主要問題是,“我可以根據表示按鈕文本的字符串數組或字符串集合創建一堆 JButton”嗎?正如您所期望的那樣,答案是肯定的,而且很容易. 例如,假設您想要一組代表一年中月份的按鈕,您可以從一組月份名稱開始,如下所示:

private static final String[] MONTHS = { 
        "January", "February", "March", "April", "May", 
        "June", "July", "August", "September", "October", 
        "November", "December" };

然后遍歷這個數組,創建顯示數組中名稱的按鈕:

for (String month : MONTHS) {
    JButton button = new JButton(month);
    someJPanel.add(button);
}

您將要遇到的問題是,如何確定按下了哪個按鈕,這是一個重要的信息。 這可以通過多種方式解決,最簡單的是將感興趣的 String 傳遞給按鈕的 ActionListener。 這些偵聽器可以使用 lambda 表達式“在線”創建,如下所示:

for (String month : MONTHS) {
    JButton button = new JButton(month);
    button.addActionListener(e -> monthButtonListener(month));
    someJPanel.add(button);
}

這個 lambda 調用了一個方法monthButtonListener(...) ,它通過 String 參數獲取按鈕的文本:

private void monthButtonListener(String month) {
    // the month name is passed into the parameter and can be used however desired
    // here as an example, by printing out the String:
    System.out.println("Month selected: " + month);
}

獲取按鈕文本的另一種常見方法是通過其動作偵聽器的“動作命令”屬性,該屬性可以從傳遞到偵聽器的 actionPerformed 方法的 ActionEvent 參數中獲取,如下所示:

再次創建按鈕,但這次將 ActionEvent 參數傳遞給 monthButtonListener:

for (String month : MONTHS) {
    JButton button = new JButton(month);
    button.addActionListener(e -> monthButtonListener(e));
    add(button);
}

然后更改 monthButtonListener 方法以接受 ActionEvent 參數並提取其操作命令屬性:

private void monthButtonListener(ActionEvent e) {
    // can also get the button's text as its "actionCommand":
    System.out.println("Button text: " + e.getActionCommand());
}

一個小的演示程序可能像這樣:

在此處輸入圖像描述

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class ButtonFoo01 extends JPanel {
    private static final String[] MONTHS = { 
            "January", "February", "March", "April", "May", 
            "June", "July", "August", "September", "October", 
            "November", "December" };
    
    public ButtonFoo01() {
        int gap = 3;
        setLayout(new GridLayout(0, 4, gap, gap));
        setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
        
        for (String month : MONTHS) {
            JButton button = new JButton(month);
            button.addActionListener(e -> monthButtonListener(e));
            add(button);
        }
    }
    
    private void monthButtonListener(ActionEvent e) {
        System.out.println("Button text: " + e.getActionCommand());
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            ButtonFoo01 mainPanel = new ButtonFoo01();

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

但...

回答了直接問題后,還必須考慮整體問題,即使用 Swing GUI 創建准確日歷表示的問題,該問題涉及非常適合使用相對較新的 DateTime Java 庫的日歷邏輯。 這個庫使得創建月組合框變得相當容易,因為可以使用庫的 Month 枚舉作為 JComboBox 的數據核心:

private JComboBox<Month> monthCombo = new JComboBox<>(Month.values());

年份可以由 JSpinner 表示,它使用已設置為所需開始和結束年份的 SpinnerNumberModel:

private JSpinner yearSpinner = new JSpinner(new SpinnerNumberModel(2022, 1900, 3000, 1));

我還會更改微調器的編輯器,使其不顯示千位逗號分隔符:

JSpinner.NumberEditor editor = new JSpinner.NumberEditor(yearSpinner, "#");
yearSpinner.setEditor(editor);

此外,我們可以向 JComboBox 添加與 JSpinner 相同的偵聽器,該偵聽器采用兩個值並為所選年份找到正確的月份:

yearSpinner.addChangeListener(ce -> dateChanged());
monthCombo.addItemListener(ie -> dateChanged());

使用dateChanged()方法:

private void dateChanged() {
    int year = (int) yearSpinner.getValue();
    Month month = (Month) monthCombo.getSelectedItem();
    LocalDate date = LocalDate.of(year, month, 1);
    
    // this notifies the JPanel that displays the dates of the selected month and year
    daysOfMonthPanel.setDate(date);
}

示例程序可能類似於:

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.Locale;
import javax.swing.*;

@SuppressWarnings("serial")
public class CalendarGui extends JPanel {
    public static final String LOCAL_DATE = "local date";
    private JSpinner yearSpinner = new JSpinner(new SpinnerNumberModel(2022, 1900, 3000, 1));
    private JComboBox<Month> monthCombo = new JComboBox<>(Month.values());
    private DaysOfTheMonthPanel daysOfMonthPanel = new DaysOfTheMonthPanel();

    public CalendarGui() {
        JSpinner.NumberEditor editor = new JSpinner.NumberEditor(yearSpinner, "#");
        yearSpinner.setEditor(editor);
        yearSpinner.addChangeListener(ce -> dateChanged());
        monthCombo.addItemListener(ie -> dateChanged());
        monthCombo.setRenderer(new MonthComboEditor());
        yearSpinner.setMaximumSize(yearSpinner.getPreferredSize());
        monthCombo.setMaximumSize(monthCombo.getPreferredSize());

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
        topPanel.add(yearSpinner);
        topPanel.add(Box.createHorizontalGlue());
        topPanel.add(monthCombo);
        
        JPanel middlePanel = new JPanel(new BorderLayout());
        middlePanel.add(new DaysOfTheWeekPanel(), BorderLayout.PAGE_START);
        middlePanel.add(daysOfMonthPanel);        

        int gap = 3;
        setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
        setLayout(new BorderLayout(gap, gap));
        add(topPanel, BorderLayout.PAGE_START);
        add(middlePanel);
        
        LocalDate now = LocalDate.now();
        yearSpinner.setValue(now.getYear());
        monthCombo.setSelectedItem(now.getMonth());
    }
    
    private void dateChanged() {
        int year = (int) yearSpinner.getValue();
        Month month = (Month) monthCombo.getSelectedItem();
        LocalDate date = LocalDate.of(year, month, 1);
        
        // this notifies the JPanel that displays the dates of the selected month and year
        daysOfMonthPanel.setDate(date);
    }

    public static void main(String[] args) {        
        SwingUtilities.invokeLater(() -> {
            CalendarGui mainPanel = new CalendarGui();

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

    private static class MonthComboEditor extends DefaultListCellRenderer {
        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
                boolean cellHasFocus) {
            String newValue = (value == null) ? "" : ((Month) value).getDisplayName(TextStyle.FULL, Locale.US);
            return super.getListCellRendererComponent(list, newValue, index, isSelected, cellHasFocus);

        }
    }
    
    private static class DaysOfTheWeekPanel extends JPanel {
        private static final float FONT_SZ = 24;
        public DaysOfTheWeekPanel() {
            setLayout(new GridLayout(1, 7));
            int numberDaysOfWk = DayOfWeek.values().length;
            for (int i = 0; i < numberDaysOfWk; i++) {
                int sundayIsZero = (i + numberDaysOfWk - 1) % numberDaysOfWk;
                JLabel wkDayLabel = new JLabel(DayOfWeek.values()[sundayIsZero].getDisplayName(TextStyle.SHORT, getLocale()));
                wkDayLabel.setHorizontalAlignment(SwingConstants.CENTER);
                Font font = wkDayLabel.getFont().deriveFont(Font.BOLD, FONT_SZ);
                wkDayLabel.setFont(font);
                add(wkDayLabel);
            }
        }
    }
    
    private class DaysOfTheMonthPanel extends JPanel {
        public DaysOfTheMonthPanel() {
            int gap = 2;
            setLayout(new GridLayout(0, 7, gap, gap));
            setBorder(BorderFactory.createLineBorder(Color.BLACK, gap));
            setBackground(Color.BLACK);
        }
        
        public void setDate(LocalDate date) {
            removeAll();
            int year = date.getYear();
            Month month = date.getMonth();
            LocalDate firstOfMonth = LocalDate.of(year, month, 1);
            DayOfWeek dayOfWeek = firstOfMonth.getDayOfWeek();
            int daysInMonth = YearMonth.of(year, month).lengthOfMonth();
            
            // fill empty slots with empty JLabels
            for (int i = 0; i < dayOfWeek.getValue() % 7; i++) {
                add(new JPanel());
            }
            
            for (int i = 1; i <= daysInMonth; i++) {
                JLabel label = new JLabel(String.valueOf(i), SwingConstants.CENTER);
                JPanel panel = new JPanel(new GridBagLayout());
                final LocalDate localDate = LocalDate.of(year, month, i);
                panel.putClientProperty(LOCAL_DATE, localDate);
                panel.setBackground(Color.WHITE);
                int topBtm = 25;
                int side = 45;
                panel.setBorder(BorderFactory.createEmptyBorder(topBtm, side, topBtm, side));
                panel.add(label);
                panel.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        String format = "MMMM dd, yyyy";
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
                        System.out.println("Date pressed: " + localDate.format(formatter));
                    }
                });
                add(panel);
            }
            
            // fill in w/ jpanels until end of month
            LocalDate lastDayOfMonth = LocalDate.of(year, month, daysInMonth);
            int lastDayOfWeek = lastDayOfMonth.getDayOfWeek().getValue();
            int daysLeft = (7 + 6 - lastDayOfWeek) % 7; 
            for (int i = 0; i < daysLeft; i++) {
                add(new JPanel());
            }
            revalidate();
            repaint();
        }
    }
}

為什么不將按鈕存儲在數組或 ArrayList 中,以便可以通過循環訪問它們? 我堅信無論如何您都會通過循環創建它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM