[英]Can I make a for statement with the names of JButtons?
我正在為 NetBeans 中僅一年的日歷編程,對於 GUI,我計划將典型的日歷作為當年的微調器。 這種組合將決定該月的第一天和最后一天在一周中的哪一天。
我編寫的代碼存在的問題是使用日歷日按鈕的名稱作為變量。 也許有辦法為 NetBeans 准備一個聲明作為按鈕名稱?
對於這個日歷,我制作了一個帶有 49 個按鈕的 JPanel(有 7 行星期,這是日歷的最大值)。 我試圖將每個按鈕命名為“N(數字)”(數字從 1 到 49)。 這樣我就可以為 function 制作一個,這樣一個月的最后一天之后的第二天的 position 將是下個月第一天的 position。
此代碼將從 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.