Dynamic Panel Content from function call - java

What I am trying to do is add two X by 2 grid panels in the first row of a 2x2 grid content panel, leaving the bottom row of the content panel blank.
To populate the cells on the top row I want to use a function which uses a loop to generate a text field and a slider. the text field calling it's input from textList[n].
So this breaks down into two primary questions.
If I have a function:
public static void makeTop(String textName) {
JTextField textBox = new JTextField(textName);
textBox.setPreferredSize(new Dimension(100,50));
textBox.setHorizontalAlignment(JTextField.CENTER);
textBox.setEditable(false);
SpinnerNumberModel numSpinner = new SpinnerNumberModel(10,0,100,1);
JSpinner spinner = new JSpinner(numSpinner);
spinner.setPreferredSize(new Dimension(100,50));
}
And a frame w/ panel:
public static void main(String[] args) {
JFrame frame = new JFrame("Frame");
frame.getContentPane().setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel cPane = new JPanel((new GridLayout(2,2)));
frame.add(cPane, BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
How could I add the text field and spinner created in makeTop to cPane?
cPane.add() doesn't like function calls, and making cPane public didn't seem to help when trying to add the content in makeTop().
Secondly, let's say makeTop is called as follows, with N being arbitrary and textList[] being populated with Strings:
for(i=N;i>0;i--){
makeTop(textList[i]);
}
How could I get the text fields and sliders to be unique instances when creating them in such a way?

cPane.add doesn't like function calls, and making cPane public didn't
seem to help when trying to add the content in makeTop()
It won't work, indeed, because by contract makeTop(String textName) is returning void. But if you make this change:
public static JPanel makeTop(String textName){
JTextField textBox = new JTextField(textName);
textBox.setPreferredSize(new Dimension(100,50));
textBox.setHorizontalAlignment(JTextField.CENTER);
textBox.setEditable(false);
SpinnerNumberModel numSpinner = new SpinnerNumberModel(10,0,100,1);
JSpinner spinner = new JSpinner(numSpinner);
spinner.setPreferredSize(new Dimension(100,50));
JPanel panel = new JPanel(new FlowLayout());
panel.add(textBox);
panel.add(spinner);
return panel;
}
Then cPane.add(makeTop("Whatever")); will work like a charm.

Related

Problems with BorderLayout() in Java

I've tried a lot of different ways, but I will explain two and what was happening (no error messages or anything, just not showing up like they should or just not showing up at all):
First, I created a JPanel called layout and set it as a BorderLayout. Here is a snippet of how I made it look:
JPanel layout = new JPanel();
layout.setLayout(new BorderLayout());
colorChoice = new JLabel("Choose your color: ");
layout.add(colorChoice, BorderLayout.NORTH);
colorBox = new JComboBox(fireworkColors);
colorBox.addActionListener(this);
layout.add(colorBox, BorderLayout.NORTH);
In this scenario what happens is they don't show up at all. It just continues on with whatever else I added.
So then I just tried setLayout(new BorderLayout()); Here is a snippet of that code:
setLayout(new BorderLayout());
colorChoice = new JLabel("Choose your color: ");
add(colorChoice, BorderLayout.NORTH);
colorBox = new JComboBox(fireworkColors);
colorBox.addActionListener(this);
add(colorBox, BorderLayout.NORTH);
In this scenario they are added, however, the width takes up the entire width of the frame and the textfield (not shown in the snippet) takes up basically everything else.
Here is what I have tried:
setPreferredSize() & setSize()
Is there something else that I am missing? Thank you.
I also should note that this is a separate class and there is no main in this class. I only say this because I've extended JPanel instead of JFrame. I've seen some people extend JFrame and use JFrame, but I haven't tried it yet.
You created a JPanel, but didn't add it to any container. It won't be visible until it is added to something (a JFrame, or another panel that is in a frame somewhere up the hierarhcy)
You added two components to the same position in the BorderLayout. The last one added is the one that will occupy that position.
Update:
You do not need to extend JFrame. I never do, instead I always extend JPanel. This makes my custom components more flexible: they can be added in another panel, or they can be added to a frame.
So, to demonstrate the problem I will make an entire, small, program:
public class BadGui
{
public static void main(String[] argv)
{
final JFrame frame = new JFrame("Hello World");
final JPanel panel = new JPanel();
panel.add(new JLabel("Hello"), BorderLayout.NORTH);
panel.add(new JLabel("World"), BorderLayout.SOUTH);
frame.setVisible(true);
}
}
In this program I created a panel, but did not add it to anything so it never becomes visible.
In the next program I will fix it by adding the panel to the frame.
public class FixedGui
{
public static void main(String[] argv)
{
final JFrame frame = new JFrame("Hello World");
final JPanel panel = new JPanel();
panel.add(new JLabel("Hello"), BorderLayout.NORTH);
panel.add(new JLabel("World"), BorderLayout.SOUTH);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
Note that in both of these, when I added something to the panel, I chose different layout parameters (one label I put in 'North' and the other in 'South').
Here is an example of a JPanel with a BorderLayout that adds a JPanel with a button and label to the "North"
public class Frames extends JFrame
{
public Frames()
{
JPanel homePanel = new JPanel(new BorderLayout());
JPanel northContainerPanel = new JPanel(new FlowLayout());
JButton yourBtn = new JButton("I Do Nothing");
JLabel yourLabel = new JLabel("I Say Stuff");
homePanel.add(northContainerPanel, BorderLayout.NORTH);
northContainerPanel.add(yourBtn);
northContainerPanel.add(yourLabel);
add(homePanel);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setTitle("Cool Stuff");
pack();
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(Frames::new);
}
}
The below suggestion is assuming that your extending JFrame.
Testing
First of all, without seeing everything, theres always a numerous amount of things you can try.
First off, after you load everything, try adding this in (Again, assuming your extending JFrame:
revalidate();
repaint();
I add this into my own Swing projects all the time, as it refreshes and checks to see that everything is on the frame.
If that doesn't work, make sure that all your JComponent's are added to your JPanel, and ONLY your JPanel is on your JFrame. Your JFrame cannot sort everything out; the JPanel does that.
JPanel window = new JPanel();
JButton button = new JButton("Press me");
add(window);
window.add(button); // Notice how it's the JPanel that holds my components.
One thing though, you still add your JMenu's and what-not through your JFrame, not your JPanel.

Creating a WordWrap method for a JTextarea - Java

I think im heading in the wrong direction. Im creating a notepad app. I have every method running perfectly except one - WordWrap
Its just a JTextarea inside a panel inside a frame.
I think i should be using a JScrollPane instead of a Textarea? Or aswell as it even?
How would i go about resizing the width of a textarea or am i correct in saying i need to insert a JScrollPane.
Edit
Ok so my attempt is gone wrong somehow. Text area doesnt work. Something possibly needs resizing.
public class TextEditor extends JFrame implements ActionListener{
JFrame textFrame = new JFrame();
JPanel textPanel = new JPanel();
JTextField textArea = new JTextField();
JScrollPane scroll = new JScrollPane(textArea);
JTextArea text = new JTextArea(24,33);
public TextEditor(String str){
super(str);
textFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
textFrame.add(textPanel);
textPanel=(JPanel)getContentPane();
textPanel.setLayout(new FlowLayout());
textPanel.setBackground(Color.WHITE);
// Create text Area
textPanel.add(scroll);
scroll.add(text);
textPanel.setFont(textAreaFont);
textArea.setFont(textAreaFont);
text.setFont(textAreaFont);
}
public static void main(String args[])
{
TextEditor notePad = new TextEditor("Notepad");
notePad.setSize(500,500);
notePad.setVisible(true);
notePad.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
Have a look at what I have tried to put together:
public class SO{
public static void main(String[] args) {
JFrame f = new JFrame();
JPanel p = new JPanel();
JTextArea outputArea = new JTextArea();
outputArea.setColumns(20);
outputArea.setRows(20);
outputArea.setLineWrap(true); //Set line wrap
outputArea.setWrapStyleWord(true); //set word wrap
JScrollPane sp = new JScrollPane(outputArea); //Create new scroll pane with textarea inside
p.add(sp); //add scrollPane to panel
f.add(p); //Add panel to frame
f.pack()
f.setLocationRelativeTo(null); //frame location
f.setVisible(true);
}
}
The scroll pane is created using the textarea in the constructor, this seems to allow the scroll pane to 'contain' the JTextArea, adding scroll bars when the text the area contains exceeds the limits. Earlier when creating the JTextArea I set two lines of code to set a word wrap on it, this stops words seeping off the sides by pushing them onto the next line. Have a look and see if it can help with your project.
Good Luck!
import java.awt.*;
import javax.swing.*;
public class TextEditor extends JFrame {
JFrame textFrame = new JFrame();
JPanel textPanel = new JPanel();
JTextArea textArea = new JTextArea(10,25);
public TextEditor(String str){
super(str);
textFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE); // nicer
add(textPanel);
textPanel.setLayout(new GridLayout());
textPanel.setBackground(Color.WHITE);
// Create text Area
JScrollPane scroll = new JScrollPane(textArea);
textPanel.add(scroll);
}
public static void main(String args[])
{
TextEditor notePad = new TextEditor("Notepad");
notePad.setVisible(true);
notePad.setDefaultCloseOperation(EXIT_ON_CLOSE);
notePad.pack();
}
}
There were so many things wrong in that short code that I lost track of the changes. Two things I can recall are:
The code was quite confused about what was a JTextField and what was a JTextArea.
It added strange things to other strange things for no apparent reason.

Can't update JPanel

I have a JTable which contains a list of item and a JPanel with some components. When I click to my button, I want all information of the selected item in the JTable will be loaded to the JPanel. At the first time, it work well but at the further times when I click to my button the Jpanel appears with empty component.
The code when clicking to my button:
jbtUpdateContract.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
Object contractID = getValueOfSelectedRow(contractTable, 0);
Contract contract = contractTransaction.getContractByID(Integer.parseInt(contractID.toString()));
//Create Jpanel to display information
jplUpdateContractForm.removeAll();
jplUpdateContractForm = createContractForm(contract);
jplUpdateContractForm.revalidate();
//Modify contract frame
jfrmUpdateContract.getContentPane().add(jplUpdateContractForm,
BorderLayout.CENTER);
jfrmUpdateContract.setSize(400, 300);
jfrmUpdateContract.setVisible(true);
jfrmUpdateContract.setResizable(false);
}
});
And my createContractForm function:
public static JPanel createContractForm(Contract contract)
{
JPanel jplContractForm = new JPanel(new SpringLayout());
JLabel jlblAppointmentDate = new JLabel("Appointment date:", JLabel.TRAILING);
jlblAppointmentDate.setName("jlblAppointmentDate");
jplContractForm.add(jlblAppointmentDate);
final JTextField jtxtAppointmentDate = new JTextField(15);
jtxtAppointmentDate.setName("jtxtAppointmentDate");
jtxtAppointmentDate.setText(contract.getAppointmentDate());
jtxtAppointmentDate.setEditable(false);
jtxtAppointmentDate.addMouseListener(appointmentDateMouseListener(jtxtAppointmentDate));
jlblAppointmentDate.setLabelFor(jtxtAppointmentDate);
jplContractForm.add(jtxtAppointmentDate);
jplContractForm.setOpaque(true);
//***Customer Cobobox
JLabel jlblCustomer= new JLabel("Customer:", JLabel.TRAILING);
jlblCustomer.setName("jlblCustomer");
jplContractForm.add(jlblCustomer);
final JComboBox jcbxCustomer = new JComboBox();
jcbxCustomer.setName("jcbxCustomer");
//Load customers from DB to combobox
Customer[] customers = customerTransaction.getAllCustomer();
for(int i = 0; i < customers.length; i++)
jcbxCustomer.addItem(customers[i]);
System.out.println("----------CUSTOMER----------" + getIndexOfCustomerComboBoxItem(jcbxCustomer, contract.getCustomerSeq()));
jcbxCustomer.setSelectedIndex(getIndexOfCustomerComboBoxItem(jcbxCustomer, contract.getCustomerSeq()));
jlblCustomer.setLabelFor(jcbxCustomer);
jplContractForm.add(jcbxCustomer);
jplContractForm.setOpaque(true);
}
Please help me to explaint why the JPanel is empty as I describes above.
Regards.
The frame is already visible, so I don't think any of these lines of code will help.
jfrmUpdateContract.setSize(400, 300);
jfrmUpdateContract.setVisible(true);
jfrmUpdateContract.setResizable(false);
The revalidate() does nothing because you haven't added the panel to the frame yet. Try the revalidate() AFTER the panel has been added to the frame.
jplUpdateContractForm = createContractForm(contract);
//jplUpdateContractForm.revalidate();
jfrmUpdateContract.getContentPane().add(jplUpdateContractForm, BorderLayout.CENTER);
jplUpdateContractForm.revalidate();
If you need more help then post a proper SSCCE.

Trying to build a GUI that would enable users to add more TextFields to it

I need to let users add more text fields to my JFrame so once the size of the containing frame being JPanel has exceeded its original value a scroll pane would step in.
In order to be able to do this, I came up with an idea to put one JButton and upon hitting it a new TextField would show up (this was my original idea which doesn't necessarily mean I am right). The problem is, once I call the ActionListener class to add more TextFields and eventually stretch its containing panel, the program asks me to make the JPanel final which in turns doesn't allow for stretching of the panel. In other words, it appears to me that I'm just beating around the bush, please help me out put this together, below is a piece of my code:
public class Button {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel p = new JPanel(new GridLayout(0, 5));
JScrollPane jsp = new JScrollPane(p);
jsp.setPreferredSize(new Dimension(300,300));
jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
JButton but = new JButton("Add");
f.add(but);
but.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int height=0;
JTextField jtx = new JTextField();
jtx.setSize(new Dimension(70,20));
jtx.setPreferredSize(new Dimension(70,20));
p.add(jtf);
height+=20;
p.setSize(new Dimension(300, height));
p.setPreferredSize(new Dimension(300, height));
}
});
f.add(jsp, BorderLayout.CENTER);
f.setLocation(300, 300);
f.setVisible(true);
f.pack();
}
}
I will give you an idea : you can add button and inside the button instruction you would add an instruction set that create text field . if you want more than once then you must handle position pointer that tell you the last place the user add text field then by updating the pointer the user can see the text in different place , if you want the user to control the position of the text then he must enter the location .

Parsed data display in JTable

I am new to Java. I have to display xml Parsed data parent nodes on JTabbedPane and child nodes in jtable into respective JTabbedPane. For parsing i have used sax parser and all the data was previously displayed in three JTextarea, I have created TabbedPane and displayed hardcoded string as title but i am not able to set Jtable into it with values.
public class JTableDisplay {
public JTableDisplay() {
JFrame frame = new JFrame("JTable Test Display");
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JTable table = new JTable();
JScrollPane tableContainer = new JScrollPane(table);
panel.add(tableContainer, BorderLayout.CENTER);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new JTableDisplay();
}
}
This is sample to create JTable after which i have to arrange the parsed data into in.
It is there. It is just not showing any data.
To make your table visible, try defining columns and rows for your table via the constructor :
JTable table = new JTable(3,4);
Get it?
Now you just need to define the tablemodel and you are set.

Categories