I am trying to make a design to my java app and I want to make 2 groups I have already done creating 2 groups using JPanel but I am trying to make a legend design type. Now here is my question is there a way to make the overflow of the JPanel visible?
Take a look at the white space in the border of the jpanel there is a jlabel there but its content are out of bound of the panel I want to show them.
here is my code:
package myproject;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUI extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel jlabel1, jlabel2, lbtitle1, lbtitle2;
private JTextArea lbresult;
private JPanel layout, group1, group2;
private JButton btnlogin;
private JTextField jtxemail, jtxpass;
public GUI() {
// TODO Auto-generated constructor stub
super("This is my interface");
setSize(500,420);
setLayout(new BorderLayout(0, 0));
doDrawing();
add(layout, BorderLayout.CENTER);
}
private void doDrawing() {
// TODO Auto-generated method stub
layout = new JPanel();
layout.setLayout(null);
layout.setBackground(Color.WHITE);
layout.setSize(this.getWidth(), this.getHeight());
group1 = createGroup(group1, 0, 15, layout.getWidth() * 50/100, 50);
lbtitle1 = new JLabel("Email");
lbtitle1.setBounds(10, -15, 100, 30);
lbtitle1.setOpaque(true);
lbtitle1.setBackground(Color.WHITE);
//create label1:
jlabel1 = new JLabel("Email: ");
jlabel1.setBounds(10, 10, 100, 30);
//create textfield1:
jtxemail = new JTextField();
jtxemail.setBounds(120, 10, 100, 30);
//add objects for the group:
group1.add(lbtitle1);
group1.add(jlabel1);
group1.add(jtxemail);
layout.add(group1);
}
private JPanel createGroup(JPanel group, int x, int y, int width, int height) {
group = new JPanel();
group.setLayout(null);
group.setBounds(x, y, 0, 0);
group.setSize(width, height);
group.setBackground(new Color(0,0,0,0));
group.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1, false));
return group;
}
}
You could do something like this using a combination of layouts. For instance if you wanted a single column of data for input, then the overall layout could be a GridLayout(0, 1), creating a grid of one column and variable number of rows. Then the rows themselves would be made of a JPanel that uses, say GridBagLayout. Something like so:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class GUI2 extends JPanel {
private static final String[][] LABELS = {
{"E-Mail", "E-Mail Address"},
{"Phone", "Phone Number"},
{"Address", "Street Address"},
{"City", "City"},
{"State", "State"} };
private static final int TXT_FIELD_COLS = 15;
private Map<String, JTextField> labelFieldMap = new HashMap<>();
public GUI2() {
setLayout(new GridLayout(0, 1));
for (String[] label : LABELS) {
add(createLegend(label));
}
}
private JPanel createLegend(String[] label) {
JLabel jLabel = new JLabel(label[1]);
JTextField txtField = new JTextField(TXT_FIELD_COLS);
labelFieldMap.put(label[0], txtField);
JPanel legendPanel = new JPanel();
legendPanel.setBorder(BorderFactory.createTitledBorder(label[0]));
legendPanel.setLayout(new GridBagLayout());
int anchor = GridBagConstraints.WEST;
int fill = GridBagConstraints.HORIZONTAL;
int ins = 3;
Insets insets = new Insets(ins, ins, ins, 3* ins);
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, anchor, fill, insets, 0, 0);
legendPanel.add(jLabel, gbc);
gbc.gridx = 1;
gbc.weightx = 0.0;
gbc.anchor = GridBagConstraints.EAST;
legendPanel.add(txtField, gbc);
return legendPanel;
}
private static void createAndShowGui() {
GUI2 mainPanel = new GUI2();
JFrame frame = new JFrame("GUI2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Related
I was wondering if there is an easier way to add vertical labels to the game board instead of adding individual Jlabels and moving them. I currently have a single letter set up and when i try to change the font size to anything over 10 font the text will become a small dot or just disaster.
public class View {
private JFrame frameMain;
private JPanel panelBoard;
private JPanel panelTitle;
private JPanel panelMain;
private JPanel panelY;
private JPanel panel2;
private JTextArea text;
private JLabel jlabel;
private JLabel jlabelY;
private List<JButton> list;
public View(){
frameMain = new JFrame();
frameMain.setLayout(new FlowLayout());
list = new ArrayList<>();
panelMain = new JPanel();
panelY = new JPanel();
panelY.setLayout(null);
panelBoard = new JPanel();
panelTitle = new JPanel();
panelMain.setLayout(new BorderLayout());
Board x = new Board();
GridLayout grid = new GridLayout(15,15);
x.createBoard();
panelBoard.setLayout(grid);
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
list.add(new JButton());
}
}
for(JButton x5:list){
panelBoard.add(x5);
}
jlabel = new JLabel("game");
jlabelY = new JLabel("A");
Dimension size = jlabelY.getPreferredSize();
jlabelY.setBounds(17,10 ,size.width,size.height);
jlabelY.setFont(new Font("Ariel", Font.BOLD, 10));
panelTitle.setPreferredSize(new Dimension(50,50));
panelY.setPreferredSize(new Dimension(25,600));
panelBoard.setPreferredSize(new Dimension(400,400));
panelMain.setPreferredSize(new Dimension(600,600));
panelY.add(jlabelY);
panelTitle.add(jlabel);
panelMain.add(panelTitle, BorderLayout.NORTH);
panelMain.add(panelBoard, BorderLayout.CENTER);
panelMain.add(panelY, BorderLayout.WEST);
frameMain.add(panelMain);
frameMain.setSize(600, 600);
frameMain.pack();
frameMain.setVisible(true);
}
You "could" do this using a GridLayout, but where's the fun in that. The following example makes use of GridBagLayout to layout the text and the buttons.
Trying to align components across containers is, well, let's just "hard" and leave it there, for this reason, the row labels and buttons are added to the same container. This ensures that the height of each row is based on the needs of the components within the row.
There's a few other ways you could do this, but this gives you the basic idea.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new View();
}
});
}
public class View {
private JFrame frameMain;
private JPanel panelBoard;
private JPanel panelTitle;
private JPanel panelMain;
private JPanel panel2;
private JTextArea text;
private JLabel jlabel;
private JLabel jlabelY;
private List<JButton> list;
public View() {
frameMain = new JFrame();
frameMain.setLayout(new FlowLayout());
list = new ArrayList<>();
panelMain = new JPanel();
panelBoard = new JPanel();
panelTitle = new JPanel();
panelMain.setLayout(new BorderLayout());
panelBoard.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
for (int y = 0; y < 15; y++) {
gbc.gridx = 0;
gbc.gridy = y;
JLabel rowLabel = new JLabel(Character.toString('A' + y));
rowLabel.setFont(new Font("Ariel", Font.BOLD, 24));
panelBoard.add(rowLabel, gbc);
for (int x = 0; x < 15; x++) {
gbc.gridx++;
JButton btn = new JButton();
list.add(btn);
panelBoard.add(btn, gbc);
}
}
jlabel = new JLabel("game");
panelTitle.add(jlabel);
panelMain.add(panelTitle, BorderLayout.NORTH);
panelMain.add(panelBoard, BorderLayout.CENTER);
frameMain.add(panelMain);
frameMain.pack();
frameMain.setVisible(true);
}
}
}
I have to make a scrollable list where I can add a panel with 3 labels many times.
I kind of made it work but the first panels are stretched and occupy all the area of the JScrollPane and I can't figure out how to fix this, I tried changing layouts many times but still didn't manage to fix it.
I want the added panel to occupy a fixed size but I can't figure this out. Example in this picture:
https://i.stack.imgur.com/LNznP.png
The one on the left is the one that I get and the one on the right (edited) is how I want it to work.
This is my first day of Swing so the code is very likely a mess, sorry in advance.
Here is the code:
public class MainWindow extends JFrame implements ActionListener{
private JPanel viewportPanel;
private JButton addButton,remButton;
private JScrollPane scrollPane;
private int counter = 0;
private JLabel dateLabel,dateLabel_1,dateLabel_2;
public MainWindow(boolean run) {
//BUTTONS
addButton = new JButton("Add");
addButton.setLocation(521, 11);
addButton.setSize(101, 100);
addButton.addActionListener(this);
remButton = new JButton("Remove");
remButton.setLocation(521, 122);
remButton.setSize(101, 100);
remButton.addActionListener(this);
//SCROLLPANE
scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(10, 11, 501, 211);
add(scrollPane);
//PANELS
viewportPanel = new JPanel(new GridLayout(0,1));
scrollPane.setViewportView(viewportPanel);
//FRAME
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 650, 273);
setResizable(false);
//setIconImage(new ImageIcon("epic.png").getImage());
setLayout(null);
if(run) setVisible(true);
add(addButton);
add(remButton);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == addButton) {
//LABELS
dateLabel = new JLabel("DATE");
dateLabel.setFont(new Font("Tahoma", Font.BOLD, 28));
dateLabel.setSize(500,500);
dateLabel_1 = new JLabel("LABEL1");
dateLabel_1.setFont(new Font("Tahoma", Font.BOLD, 22));
dateLabel_1.setBounds(10, 45, 481, 30);
dateLabel_2 = new JLabel("LABEL2");
dateLabel_2.setFont(new Font("Tahoma", Font.ITALIC, 22));
dateLabel_2.setBounds(10, 45, 481, 30);
//PANEL WITH ALL THE STUFF
JPanel componentPanel = new JPanel();
componentPanel.setLayout(new GridLayout(3, 1));
componentPanel.setMaximumSize(new Dimension(50,50));
componentPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
componentPanel.setBackground(Color.gray);
componentPanel.add(dateLabel);
componentPanel.add(dateLabel_1);
componentPanel.add(dateLabel_2);
viewportPanel.add(componentPanel); //add panel with labels to viewportpanel
counter++;
}
if(e.getSource() == remButton) {
Component[] componentList = viewportPanel.getComponents();
int lastElement = (componentList.length);
viewportPanel.remove(--lastElement);
--counter;
}
viewportPanel.revalidate();
viewportPanel.repaint();
}
}
Some help would be amazing!
First off, never do this:
setLayout(null);
Next, if you want things compressed at the top of a container, then use a layout that does this. such as a BorderLayout with the compressed items placed into a JPanel (perhaps one that uses a GridLayout) that is placed BorderLayout.PAGE_START
Actually, it looks as if your best solution is to us a JList, one that uses a custom renderer that places your time JLabel and two text JLabels into a JPanel and displays this in the list. So let's explore that.
First create a class to hold the data that is displayed by the JList, which looks to be a date and two lines of text:
public class ListItem {
private LocalDate date;
private String text1;
private String text2;
public ListItem(LocalDate date, String text1, String text2) {
super();
this.date = date;
this.text1 = text1;
this.text2 = text2;
}
public LocalDate getDate() {
return date;
}
public String getText1() {
return text1;
}
public String getText2() {
return text2;
}
}
Then let's create a renderer that a JList can use to display the above information in a JPanel. This is more complicated and requires that the class create a JPanel that places the labels where we want them, perhaps using a GridLayout with 1 column and 3 rows, plus some gaps between the rows: setLayout(new GridLayout(3, 1, 2 * gap, 2 * gap));. The class must implement the ListCellRenderer<T> interface which has one method: public Component getListCellRendererComponent(...). Java will pass in the paramters into this method, including a ListItem value, and we will use that value to fill in the JLabels that we add into this JPanel. Edited to highlight selected items.
import java.awt.*;
import java.time.format.DateTimeFormatter;
import javax.swing.*;
import javax.swing.border.Border;
#SuppressWarnings("serial")
public class ListItemRenderer extends JPanel implements ListCellRenderer<ListItem> {
private static final Color LIGHT_BLUE = new Color(204, 255, 255);
private static final Color REDDISH_GREY = new Color(205, 126, 121);
private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
private static final int GAP = 2;
private Border emptyBorder = BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP);
private Border blackBorder = BorderFactory.createLineBorder(Color.BLACK);
private Border redBorder = BorderFactory.createLineBorder(REDDISH_GREY, 2);
private JLabel dateLabel = new JLabel();
private JLabel text1Label = new JLabel();
private JLabel text2Label = new JLabel();
public ListItemRenderer() {
dateLabel.setFont(dateLabel.getFont().deriveFont(Font.BOLD, 14f));
text1Label.setFont(text1Label.getFont().deriveFont(Font.BOLD));
text2Label.setFont(text1Label.getFont().deriveFont(Font.ITALIC));
int gap = 2;
setLayout(new GridLayout(0, 1, 2 * gap, 2 * gap));
setBorder(BorderFactory.createCompoundBorder(emptyBorder, blackBorder));
add(dateLabel);
add(text1Label);
add(text2Label);
}
#Override
public Component getListCellRendererComponent(JList<? extends ListItem> list, ListItem value, int index,
boolean isSelected, boolean cellHasFocus) {
if (value != null) {
String dateText = dateFormatter.format(value.getDate());
dateLabel.setText(dateText);
text1Label.setText(value.getText1());
text2Label.setText(value.getText2());
} else {
dateLabel.setText("");
text1Label.setText("");
text2Label.setText("");
}
if (isSelected ) {
setBackground(LIGHT_BLUE);
setBorder(BorderFactory.createCompoundBorder(emptyBorder, redBorder));
} else {
setBackground(null);
setBorder(BorderFactory.createCompoundBorder(emptyBorder, blackBorder));
}
return this;
}
}
And now the main program that puts this all together, edited to show removing items:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class MainPanel extends JPanel {
DefaultListModel<ListItem> listModel = new DefaultListModel<>();
private JList<ListItem> jList = new JList<>(listModel);
private JScrollPane scrollPane = new JScrollPane(jList);
private JButton addButton = new JButton("Add");
private JButton removeButton = new JButton("Remove");
public MainPanel() {
jList.setPrototypeCellValue(new ListItem(LocalDate.now(),
"This is text 1 for testing. This is text 1 for testing. This is text 1 for testing",
"This is text 2 for testing. This is text 2 for testing. This is text 2 for testing"));
jList.setVisibleRowCount(4);
jList.setCellRenderer(new ListItemRenderer());
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 3, 3));
buttonPanel.add(addButton);
buttonPanel.add(removeButton);
addButton.setMnemonic(KeyEvent.VK_A);
removeButton.setMnemonic(KeyEvent.VK_R);
addButton.addActionListener(e -> addEvent());
removeButton.addActionListener(e -> removeEvent());
JPanel rightPanel = new JPanel();
rightPanel.add(buttonPanel);
int gap = 5;
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
setLayout(new BorderLayout());
add(scrollPane);
add(rightPanel, BorderLayout.LINE_END);
}
private void removeEvent() {
int[] selectedIndices = jList.getSelectedIndices();
for (int i = selectedIndices.length - 1; i >= 0; i--) {
listModel.remove(selectedIndices[i]);
}
}
private void addEvent() {
// this adds random stuff to the JList
String text1 = "Some random text: " + randomText();
String text2 = "Some random text: " + randomText();
listModel.addElement(new ListItem(LocalDate.now(), text1, text2));
// TODO: change this so that it adds *real* data to the JList
}
private String randomText() {
Random random = new Random();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 2 + random.nextInt(3); i++) {
for (int j = 0; j < 3 + random.nextInt(5); j++) {
char c = (char) ('a' + random.nextInt('z' - 'a'));
builder.append(c);
}
builder.append(" ");
}
return builder.toString();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Output would look like:
I have a JTextArea that is filled with numbers with no duplicates. There is an add and remove button. I have programmed the add button, but I am struggling with programming the remove button. I know how to remove the number from the array, but I'm not sure how to remove the number from the text area.
How do I remove a line from a text area that contains a certain number?
Extra notes:
The only input is integers.
Your question may in fact be an XY Problem where you ask how to fix a specific code problem when the best solution is to use a different approach entirely. Consider using a JList and not a JTextArea. You can easily rig it up to look just like a JTextArea, but with a JList, you can much more easily remove an item such as a line by removing it from its model.
For example:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class NumberListEg extends JPanel {
private static final int VIS_ROW_COUNT = 10;
private static final int MAX_VALUE = 10000;
private DefaultListModel<Integer> listModel = new DefaultListModel<>();
private JList<Integer> numberList = new JList<>(listModel);
private JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, MAX_VALUE, 1));
private JButton addNumberButton = new JButton(new AddNumberAction());
public NumberListEg() {
JPanel spinnerPanel = new JPanel();
spinnerPanel.add(spinner);
JPanel addNumberPanel = new JPanel();
addNumberPanel.add(addNumberButton);
JPanel removeNumberPanel = new JPanel();
JButton removeNumberButton = new JButton(new RemoveNumberAction());
removeNumberPanel.add(removeNumberButton);
JPanel eastPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
// gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(3, 3, 3, 3);
eastPanel.add(spinner, gbc);
gbc.gridy = GridBagConstraints.RELATIVE;
eastPanel.add(addNumberButton, gbc);
eastPanel.add(removeNumberButton, gbc);
// eastPanel.add(Box.createVerticalGlue(), gbc);
numberList.setVisibleRowCount(VIS_ROW_COUNT);
numberList.setPrototypeCellValue(1234567);
numberList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane listPane = new JScrollPane(numberList);
listPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
setLayout(new BorderLayout());
add(listPane, BorderLayout.CENTER);
add(eastPanel, BorderLayout.LINE_END);
}
private class AddNumberAction extends AbstractAction {
public AddNumberAction() {
super("Add Number");
putValue(MNEMONIC_KEY, KeyEvent.VK_A);
}
#Override
public void actionPerformed(ActionEvent arg0) {
int value = (int) spinner.getValue();
if (!listModel.contains(value)) {
listModel.addElement(value);
}
}
}
private class RemoveNumberAction extends AbstractAction {
public RemoveNumberAction() {
super("Remove Number");
putValue(MNEMONIC_KEY, KeyEvent.VK_R);
}
#Override
public void actionPerformed(ActionEvent e) {
Integer selection = numberList.getSelectedValue();
if (selection != null) {
listModel.removeElement(selection);
}
}
}
private static void createAndShowGui() {
NumberListEg mainPanel = new NumberListEg();
JFrame frame = new JFrame("Gui");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
can not be remove from the array,you can to make index to be empty,for example String a= Integer.toString(type for int),then a.replace("your int","");
This code uses the card layout, as I want to change the window display rather than have multiple windows (or frames). Therefore I want multiple panels, which seems to work.
However within the panels I want to use the gridbag layout for positioning components. But it's not working! It acts as a flow layout. Can anyone help me get over this hurdle? Please.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class another
{
private JPanel contentPane;
private MyPanel panel1;
private MyPanel2 panel2;
private void displayGUI()
{
JFrame frame = new JFrame("Card Layout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new CardLayout());
panel1 = new MyPanel(contentPane);
panel2 = new MyPanel2();
contentPane.add(panel1, "Panel 1");
contentPane.add(panel2, "Panel 2");
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new another().displayGUI();
}
});
}
}
class MyPanel extends JPanel {
private JTextField How;
private JLabel jcomp2;
private JLabel jcomp3;
private JButton jcomp4;
private JPanel contentPane;
private JPanel myPanel1;
public MyPanel(JPanel panel)
{
contentPane = panel;
//construct components
How = new JTextField (1);
jcomp2 = new JLabel ("Label2");
jcomp3 = new JLabel ("Label3");
jcomp4 = new JButton ("openNewWindow");
myPanel1 = new JPanel();
//adjust size and set layout
setPreferredSize (new Dimension (600, 600));
setLayout (new GridBagLayout());
//set component bounds (only needed by Absolute Positioning)
/*
How.setBounds (245, 50, 60, 25);
jcomp2.setBounds (35, 30, 185, 50);
jcomp3.setBounds (250, 30, 60, 20);
jcomp4.setLocation(0, 0);
jcomp4.setSize(315, 25);
*/
insert(jcomp2, 0, 0, 1, 1);
insert(jcomp3, 0, 1, 1, 1);
insert(jcomp4, 1, 0, 1, 1);
jcomp4.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
CardLayout cardLayout = (CardLayout) contentPane.getLayout();
cardLayout.next(contentPane);
}
});
//add components
//add (How);
add (jcomp2);
add (jcomp3);
add (jcomp4);
}
public void insert(Component c, int gridX, int gridY, int gridW, int gridH)
{
GridBagConstraints constraint = new GridBagConstraints();
constraint.gridx = gridX;
constraint.gridy = gridY;
constraint.gridwidth = gridW;
constraint.gridheight = gridH;
constraint.anchor = GridBagConstraints.LINE_START;
myPanel1.add(c, constraint);
}
}
class MyPanel2 extends JPanel {
private JButton jcomp1;
private JButton jcomp2;
private JButton jcomp3;
private JTextField jcomp4;
public MyPanel2() {
//construct components
jcomp1 = new JButton ("test1");
jcomp2 = new JButton ("test2");
jcomp3 = new JButton ("test3");
jcomp4 = new JTextField (5);
//adjust size and set layout
setPreferredSize (new Dimension (395, 156));
setLayout (null);
//set component bounds (only needed by Absolute Positioning)
jcomp1.setBounds (20, 45, 100, 25);
jcomp2.setBounds (135, 60, 100, 25);
jcomp3.setBounds (260, 35, 100, 25);
jcomp4.setBounds (105, 115, 100, 25);
//add components
add (jcomp1);
add (jcomp2);
add (jcomp3);
add (jcomp4);
}
}
You look to be unnecessarily over-complicating things. You create a JPanel called contentPane and give it a CardLayout, all well and good, but then for some reason you pass that contentPane JPanel into the MyPanel constructor,
JPanel contentPane = new JPanel();
contentPane.setLayout(new CardLayout());
panel1 = new MyPanel(contentPane);
panel2 = new MyPanel2();
and then within the constructor you assign components to this same contentPane JPanel -- but why? You assign GridBagLayout to the MyPanel this instance, but then add components to the myPanel1 variable within it in a GridBag way when this JPanel has the JPanel default FlowLayout:
class MyPanel extends JPanel {
// ....
private JPanel contentPane;
private JPanel myPanel1;
public MyPanel(JPanel panel) {
contentPane = panel;
// ....
myPanel1 = new JPanel();
setLayout (new GridBagLayout()); // you set *** this *** to GridBagLayout
insert(jcomp2, 0, 0, 1, 1);
insert(jcomp3, 0, 1, 1, 1);
insert(jcomp4, 1, 0, 1, 1);
add (jcomp2); // and then you add components to this without GridBagConstraints ?
add (jcomp3);
add (jcomp4);
}
public void insert(Component c, int gridX, int gridY, int gridW, int gridH) {
// ....
// but then add components in a GridBagLayout way into the myPanel1 JPanel???
myPanel1.add(c, constraint);
}
}
Better to set myPanel to use GridBagLayout:
// adjust size and set layout
setPreferredSize(new Dimension(600, 600));
// setLayout(new GridBagLayout());
myPanel1.setLayout(new GridBagLayout());
Rather than this
Again it seems that you're over-complicating what should be a simple endeavor.
For example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class SimpleCardExample extends JPanel {
private static final int EB_GAP = 8;
private CardLayout cardLayout = new CardLayout();
public SimpleCardExample() {
setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
setLayout(cardLayout);
add(new GridBagPanel(this), GridBagPanel.class.getSimpleName());
add(new NextPanel(this), NextPanel.class.getSimpleName());
}
public void nextCard() {
cardLayout.next(this);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SimpleCardExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleCardExample());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class GridBagPanel extends JPanel {
private static final int GAP = 6;
private static final Insets GBC_INSETS = new Insets(GAP, GAP, GAP, GAP);
public GridBagPanel(SimpleCardExample scExample) {
setLayout(new GridBagLayout());
add(new JLabel("Title Goes Here", SwingConstants.CENTER), createGbc(0, 0, 2, 1));
add(new JLabel("Name:"), createGbc(0, 1, 1, 1));
add(new JTextField(15), createGbc(1, 1, 1, 1));
add(new JLabel("Phone:"), createGbc(0, 2, 1, 1));
add(new JTextField(15), createGbc(1, 2, 1, 1));
add(new JLabel("Address:"), createGbc(0, 3, 1, 1));
add(new JTextField(15), createGbc(1, 3, 1, 1));
add(new JButton(new NextAction("Next", scExample)), createGbc(0, 4, 2, 1));
}
private GridBagConstraints createGbc(int x, int y, int w, int h) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = w;
gbc.gridheight = h;
gbc.insets = GBC_INSETS;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = x == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
return gbc;
}
}
class NextPanel extends JPanel {
public NextPanel(SimpleCardExample scExample) {
add(new JButton(new NextAction("Next", scExample)));
}
}
class NextAction extends AbstractAction {
private SimpleCardExample scExample;
public NextAction(String name, SimpleCardExample scExample) {
super(name);
this.scExample = scExample;
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
scExample.nextCard();
}
}
Can someone please tell me what's wrong with this code?
I need it to pop up a frame and fill the frame with certain field a namer field and an intake field and also display a button at the bottom of the grid.
Any help would be welcomed, Thanks!!
import java.awt.*;
import javax.swing.*;
public class FrameDemo
//To create the gui and show it.
{
public static void createAndShowGUI()
{
//create and set up the window.
JFrame frame = new JFrame("RungeKutta");
GridLayout first = new GridLayout(1,14);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create, name and Populate TextField
JTextField PL = new JTextField("Pendulum Length", 20);
//Set TextField to Uneditable. Each will have Empty Field Below For Variables
PL.setEditable(false);
//Set Textfield for user entered dat
JTextField PLv = new JTextField();
//Allow handler for user input on Empty Textfield?
JTextField AD = new JTextField("Angular Displacement", 20);
AD.setEditable(false);
JTextField ADv = new JTextField();
JTextField AV = new JTextField("Angular Velocity", 20);
AV.setEditable(false);
JTextField Avv = new JTextField();
JTextField TS= new JTextField("Time Steps", 20);
TS.setEditable(false);
JTextField TSv = new JTextField();
JTextField MT = new JTextField("Max Time", 20);
MT.setEditable(false);
JTextField MTv = new JTextField();
JTextField V = new JTextField("Viscosity (0-1)", 20);
V.setEditable(false);
JTextField Vv = new JTextField();
//Create Button to Restart
JButton BNewGraph = new JButton("Draw New Graph"); //Button to restart entire drawing process
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension(600,500));
frame.getContentPane().add(PL, first);
frame.getContentPane().add(PLv, first);
frame.getContentPane().add(AD, first);
frame.getContentPane().add(ADv, first);
frame.getContentPane().add(AV, first);
frame.getContentPane().add(Avv, first);
frame.getContentPane().add(TS, first);
frame.getContentPane().add(TSv, first);
frame.getContentPane().add(MT, first);
frame.getContentPane().add(MTv, first);
frame.getContentPane().add(V, first);
frame.getContentPane().add(Vv, first);
frame.getContentPane().add(BNewGraph, first);
//display the window
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
//add job to event scheduler
//create and show GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
This is not how you use GridLayout:
frame.getContentPane().add(PL, first);
Instead you'd set the container's layout using the layout manager:
frame.getContentPane().setLayout(first);
and then add components to the container:
frame.getContentPane().add(PL);
frame.getContentPane().add(PLv);
frame.getContentPane().add(AD);
frame.getContentPane().add(ADv);
frame.getContentPane().add(AV);
frame.getContentPane().add(Avv);
frame.getContentPane().add(TS);
frame.getContentPane().add(TSv);
frame.getContentPane().add(MT);
frame.getContentPane().add(MTv);
// and so on for all the components.
You will want to read the tutorial on how to use GridLayout which you can find here: GridLayout Tutorial.
As an aside, note that this:
frame.getContentPane().add(PL);
can be shortened to this:
frame.add(PL);
Also you will want to study and learn Java naming conventions: class names begin with an upper case letter and all method and variables with lower case letters. Also avoid variable names like pl or plv, or ad or adv, and instead use names that are a little bit longer and have meaning, names that make your code self-commenting. So instead of AD, consider angularDisplacementField for the JTextfield's name.
Myself, I'd use a GridBagLayout and do something like:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.*;
public class GuiDemo extends JPanel {
// or better -- use an enum for this
public static final String[] FIELD_LABELS = {
"Pendulum Length", "Angular Displacement", "Angular Velocity",
"Time Steps", "Max Time", "Viscocity (0-1)"
};
private static final int TEXT_FIELD_COLUMNS = 10;
private static final int GAP = 3;
private static final Insets RIGHT_GAP_INSETS = new Insets(GAP, GAP, GAP, 3 * GAP);
private static final Insets BALANCED_INSETS = new Insets(GAP, GAP, GAP, GAP);
private Map<String, JTextField> labelFieldMap = new HashMap<>();
public GuiDemo() {
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
int row = 0;
// to make sure that no focusAccelerator is re-used
Set<Character> focusAccelSet = new HashSet<>();
for (String fieldLabelLText : FIELD_LABELS) {
JLabel fieldLabel = new JLabel(fieldLabelLText);
JTextField textField = new JTextField(TEXT_FIELD_COLUMNS);
labelFieldPanel.add(fieldLabel, getGbc(row, 0));
labelFieldPanel.add(textField, getGbc(row, 1));
labelFieldMap.put(fieldLabelLText, textField);
for (char c : fieldLabelLText.toCharArray()) {
if (!focusAccelSet.contains(c)) {
textField.setFocusAccelerator(c);
fieldLabel.setDisplayedMnemonic(c);
focusAccelSet.add(c);
break;
}
}
row++;
}
JButton button = new JButton(new DrawGraphAction("Draw New Graph"));
labelFieldPanel.add(button, getGbc(row, 0, 2, 1));
setLayout(new BorderLayout(GAP, GAP));
add(labelFieldPanel, BorderLayout.CENTER);
}
private class DrawGraphAction extends AbstractAction {
public DrawGraphAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO calculation method
}
}
public static GridBagConstraints getGbc(int row, int column) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = column;
gbc.gridy = row;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
if (column == 0) {
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = RIGHT_GAP_INSETS;
} else {
gbc.anchor = GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = BALANCED_INSETS;
}
return gbc;
}
public static GridBagConstraints getGbc(int row, int column, int width, int height) {
GridBagConstraints gbc = getGbc(row, column);
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.insets = BALANCED_INSETS;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Gui Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GuiDemo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}