HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Using swing and creating JPanel

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
creatingjpanelswingusingand

Problem

I watched bunch of videos about swing and GUI in general and created my first component (correct me if it is not one).

JPanel class:

```
package gui.pane;

import javax.swing.*;
import javax.swing.event.EventListenerList;
import java.awt.*;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class CalendarPanel extends JPanel {
private List dateButtons = new ArrayList<>();
private Calendar selectedDate;
private final JPanel datePanel;
private EventListenerList listenerList = new EventListenerList();

public CalendarPanel() {
this(Calendar.getInstance());
}

public CalendarPanel(Calendar selectedDate) {
this.selectedDate = selectedDate;
setBorder(BorderFactory.createTitledBorder("Calendar"));

// year combo box
final JComboBox yearComboBox = new JComboBox<>(getYearList(selectedDate.get(Calendar.YEAR)));
yearComboBox.addActionListener( e -> {
selectedDate.set(Calendar.YEAR, (Integer) yearComboBox.getSelectedItem());
updateDateButtons();
}
);

//month combo box
final JComboBox monthComboBox = new JComboBox<>(new DateFormatSymbols().getMonths());
monthComboBox.setSelectedIndex(selectedDate.get(Calendar.MONTH));
monthComboBox.addActionListener( e -> {
selectedDate.set(Calendar.MONTH, monthComboBox.getSelectedIndex());
updateDateButtons();
}
);

// creating panels
final JPanel calendarPanel = new JPanel();
calendarPanel.setLayout(new BorderLayout());

// create month and year panel
final JPanel MonthAndYearPanel = new JPanel();
MonthAndYearPanel.setLayout(new FlowLayout());

// add year and month combo boxes to sub panel
MonthAndYearPanel.add(yearComboBox);
MonthAndYearPanel.add(monthComboBox);

// creates date

Solution

I think you are being too harsh on yourself. Your code is not particularly messy. It's quite difficult to build up a Swing component without code starting to feel a little untidy. I occasionally split such code into builder methods (e.g. private JPanel buildSomeComplicatedPanel()), but I think your code is fine in that regard.

To answer your stream question, if you use boxed() you can convert a primitive int stream into an Integer stream:

IntStream.range(0, 10).boxed().map(i -> i + year).toArray(size -> new Integer[size]);


However, since IntStream::range takes start and end parameters, you can simply this to:

IntStream.range(year, year + 10).boxed().toArray(size -> new Integer[size]);


Other observations:

-
Your JComboBox objects should use generic types. I.e. JComboBox yearComboBox and JComboBox monthComboBox.

-
Most of your classes are missing a serialVersionUID value. Your IDE ought to prompt you about this. (Eclipse certainly does).

-
(Very minor, more of an FYI...) Methods declared in interfaces are always public, so you don't need to include that keyword in each method signature.

-
Your CinemaFrame class extends JFrame. However, most Swing gurus would encourage you to use composition rather than inheritance:

public class CinemaFrame {

  private final JFrame frame;

  public CinemaFrame(String title) {

    frame = new JFrame(title);
    frame.setLayout(new GridBagLayout());
    CalendarPanel calendarPanel = new CalendarPanel();
    calendarPanel.addCalendarListener(e -> System.out.println(e.getSource()));
    frame.add(calendarPanel);
    frame.pack(); // You may wish to do this in the constructor
  }

  public void showFrame() {
    frame.setVisible(true);
  }

  // Example main method I used for testing...
  public static void main(String[] args) throws Exception {
    SwingUtilities.invokeLater(() -> new CinemaFrame("Foo").showFrame());
  }
}


-
Closing your frame doesn't currently end your program. You may want to add frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); into your CinemaFrame class.

Code Snippets

IntStream.range(0, 10).boxed().map(i -> i + year).toArray(size -> new Integer[size]);
IntStream.range(year, year + 10).boxed().toArray(size -> new Integer[size]);
public class CinemaFrame {

  private final JFrame frame;

  public CinemaFrame(String title) {

    frame = new JFrame(title);
    frame.setLayout(new GridBagLayout());
    CalendarPanel calendarPanel = new CalendarPanel();
    calendarPanel.addCalendarListener(e -> System.out.println(e.getSource()));
    frame.add(calendarPanel);
    frame.pack(); // You may wish to do this in the constructor
  }

  public void showFrame() {
    frame.setVisible(true);
  }

  // Example main method I used for testing...
  public static void main(String[] args) throws Exception {
    SwingUtilities.invokeLater(() -> new CinemaFrame("Foo").showFrame());
  }
}

Context

StackExchange Code Review Q#85753, answer score: 3

Revisions (0)

No revisions yet.