I have spent all day on the Web and on this site looking for an answer to my problem, and hope you guys can help. First of all, I am trying to display the contents of an ArrayList to a JTextArea when I select the 'report' JButton. The array list is in another class separate from the text area. My problem stems from the fact that the array list is an array of objects, so that when I try to display it I get the error:
The method append(String) in the type JTextArea is not applicable
for the arguments (ArrayList.Account.TransactionObject>)
I can display the array list just fine in the console window but am stumped when it comes to displaying it in the text area. I'm under the assumption that there must be some kind of issue converting the Object to a String, because I have been unable to cast it to a String or call a toString method with the array list. Here is the relevant parts of my code.....
This is the portion in the AccountUI class where I created the JTextArea:
private JPanel get_ReportPane()
{
JPanel JP_reportPane = new JPanel(new BorderLayout());
Border blackline = BorderFactory.createLineBorder(Color.BLACK);
TitledBorder title = BorderFactory.createTitledBorder(blackline, "Transaction Report");
title.setTitleJustification(TitledBorder.CENTER);
JP_reportPane.setBorder(title);
/* Create 'labels' grid and JLabels */
JPanel report_labels = new JPanel(new GridLayout(2, 1, 5, 5));
report_labels.add(new JLabel("Current Account Balance: ", SwingConstants.RIGHT));
report_labels.add(new JLabel("Account Creation Date: ", SwingConstants.RIGHT));
JP_reportPane.add(report_labels, BorderLayout.WEST);
/* Create 'data' grid and text fields */
JPanel JP_data = new JPanel(new GridLayout(2, 1, 5, 5));
JP_data.add(TF_balance2 = new JTextField(10));
TF_balance2.setBackground(Color.WHITE);
TF_balance2.setEditable(false);
JP_data.add(TF_created = new JTextField(10));
TF_created.setBackground(Color.WHITE);
TF_created.setEditable(false);
JP_reportPane.add(JP_data, BorderLayout.CENTER);
/* Create 'buttons' grid and buttons */
JPanel JP_buttons = new JPanel(new GridLayout(2, 1, 5, 5));
JButton JB_report = new JButton("Report");
JB_report.setBackground(Color.GRAY);
JB_report.setMargin(new Insets(3, 3, 3, 3));
JB_report.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
reportAccount();
}
});
JP_buttons.add(JB_report);
JButton JB_close = new JButton("Close");
JB_close.setBackground(Color.GRAY);
JB_close.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
JP_buttons.add(JB_close);
JP_reportPane.add(JP_buttons, BorderLayout.EAST);
/* Create text area and scroll pane */
reportArea.setBorder(blackline);
reportArea.setForeground(Color.BLUE);
reportArea.setLineWrap(true);
reportArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(reportArea);
reportArea.setEditable(false);
JP_reportPane.add(scrollPane, BorderLayout.SOUTH);
return JP_reportPane;
}
This is the method (called from JB_reportAction listener class shown above) where I try to display the array list in the text area (also in AccountUI class):
/**
* Method used to display account transaction history in the text field.
*/
protected void reportAccount()
{
reportArea.append(A.getTransactions());
}
And this is the method in the Account class that I am able to display the Array contents in a console output, but have been unable to figure out how to pass the Array contents to the AccountUI class as a String to display in the text area:
public ArrayList<TransactionObject> getTransactions()
{
for (int i = 0; i < transactionList.size(); i++)
{
System.out.println(transactionList.get(i));
System.out.println("\n");
}
return transactionList;
}
I hope I have clarified my issue without confusing anyone. Any insight would be much appreciated.
Call toString() on the list:
reportArea.append(A.getTransactions().toString());
Or, if you want to display the elements of the list in a different format, loop over the elements:
for (TransactionObject transaction : A.getTransactions()) {
reportArea.append(transaction.toString());
reportArea.append("\n");
}
Loops and types are an essential part of programming. You shouldn't use Swing if you don't understand loops and types.
Also, please respect the Java naming conventions. Variables start with a lower-case letter, and don't contain underscore. They're camelCased.
If you want to append content of objects in ArrayList to JTextArea you can use this :
for (Object obj : arrayList) {
textArea.append(obj.toString() + "");
}
You have to implement and override toString for TransactionObject.
Related
I cannot find out why this will not show the contents:
public class Bans implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
draw();
}
public static JFrame frame;
public static void draw() {
frame = new JFrame("Ban History");
frame.setPreferredSize(new Dimension(575,250));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JLabel label = new JLabel("Ban History");
label.setFont(Main.header);
label.setHorizontalAlignment(SwingConstants.CENTER);
JPanel container = new JPanel();
JPanel border = new JPanel();
JScrollPane scrPane = new JScrollPane(border);
border.add(container);
container.setLayout(new GridLayout(0,1));
scrPane.setBorder(null);
for(Ban ban : Main.banlist) {
System.out.println(ban.id);
JPanel whitespace = new JPanel();
JPanel panel = new JPanel();
panel.setBackground(Color.getHSBColor(176F, 25.46F, 65.12F));
panel.setPreferredSize(new Dimension(510,0));
panel.setLayout(new GridLayout(0,2));
JLabel banDate = new JLabel();
banDate.setText("(#" + ban.id + ") Ban Date: " + ban.banDate.toString() + " ");
banDate.setFont(Main.body);
panel.add(banDate);
JLabel banName = new JLabel();
banName.setText("Banned By: " + ban.bannedByName);
banName.setFont(Main.body);
panel.add(banName);
JLabel banReason = new JLabel();
banReason.setText("Reason: " + ban.banReason);
banReason.setFont(Main.body);
panel.add(banReason);
JLabel banTime = new JLabel();
banTime.setText("Ban Time: " + ban.banTime);
banTime.setFont(Main.body);
banTime.setHorizontalAlignment(SwingConstants.RIGHT);
panel.add(banTime);
container.add(whitespace);
whitespace.add(panel);
}
frame.add(label,BorderLayout.PAGE_START);
frame.add(scrPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
It was working earlier, however now none of the contents of the ScrollPane show. I'm fairly new with Swing, however I would think that this should work. Yes, there are contents in the table. When ran it does print out 5 id numbers, which correspond to the correct numbers on the MySQL server, so that should be working fine.
The content is being added, but isn't being displayed because of how you have designed your layout, as the panels representing your bans have no height:
panel.setPreferredSize(new Dimension(510,0));
By following #FredK's suggestions in the comments, you can maintain the effect of your whitespace panel by applying a vertical gap between the rows in your layout. This is provided by another constructor available within GridLayout: GridLayout(int rows, int cols, int hgap, int vgap)
There are some demos available here: How to Use GridLayout
By mocking up some bans, I got the following with your code:
Note: By applying the suggestions (with a vgap of 5) the output was the same as the above
Side note: If you find something was working earlier it tends to be from a change you've made. If you use IntelliJ as your IDE there is a helpful feature for this called a Local History. By right clicking on the class you can see line-by-line comparisons of changes you made to the class with time stamps, similar to source control. You can read more here: Using Local History
I'm not saying you have to change your IDE, but as a beginner if you are doing a lot of experimentation you may find some benefit in it
I have a textfield within a fixed-width panel of 200 pixels. This textfield is used to search amongst products, once we type in something, it shows the results in a combobox, here's how it works:
public void setupAutoComplete(final JTextField txtInput) {
final DefaultComboBoxModel model = new DefaultComboBoxModel();
cbInput = new JComboBox(model) {
public Dimension getPreferredSize() {
return new Dimension(super.getPreferredSize().width, 0);
}
};
txtInput.setLayout(new BorderLayout());
txtInput.add(cbInput, BorderLayout.SOUTH);
}
I need the combobox to be as large as the longest result shown, but I can't get it to be larger than the textfield for now, is there a way to do it without having to make the textfield larger and therefore the panel where's it's contained also?
I am trying to create a simple GUI that simulates a record store. I am still in the beginning stages.
I am running into trouble when I try to add text to describe what the user is expected to enter in the text field.
In addition, I am also having trouble positioning every textfield on its own line. In other words if there is space for two textfields in one line, then it displays in one line, and I am trying to display every text field on its own line.
This is what I tried so far:
item2 = new JTextField("sample text");
However the code above just adds default text within the text field, which is not what I need :/
I appreciate all the help in advance.
public class MyClass extends JFrame{
private JTextField item1;
private JTextField item2;
public MyClass(){
super("Matt's World of Music");
setLayout(new FlowLayout());
item1 = new JTextField();
item2 = new JTextField();
add(item1);
add(item2);
thehandler handler = new thehandler();
item1.addActionListener(handler);
item2.addActionListener(handler);
}
}
For your first problem, you need to use a JLabel to display your text. The constructor is like this:
JLabel label = new JLabel("Your text here");
Works really well in GUI.
As for getting things on their own lines, I recommend a GridLayout. Easy to use.
In your constructor, before adding anything, you do:
setLayout(new GridLayout(rows,columns,x_spacing,y_spacing));
x_spacing and y_spacing are both integers that determine the space between elements horizontally and vertically.
Then add like you have done. Fiddle around with it and you'll get it worked out.
So your final would look like:
setLayout(new GridLayout(2,2,10,10));
add(new JLabel("Text 1"));
add(text1);
add(new JLabel("text 2"));
add(text2);
You could just use a JLabel to label your textfields.
JLabel label1 = new JLabel("Item 1: ");
add(label1);
add(item1);
If you really want text inside the fields, you could set the text in the field with the constructor, and then add a MouseListener to clear the text on click:
item1 = new JTextField("Text");
item1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (item1.getText().equals("Text")) // User has not entered text yet
item1.setText("");
}
});
Or, (probably better) use a FocusListener:
item1 = new JTextField("Text");
item1.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
if (item1.getText().equals("Text")) // User has not entered text yet
item1.setText("");
}
public void focusLost(FocusEvent e) {
if (item1.getText().equals("")) // User did not enter text
item1.setText("Text");
}
});
As for layout, to force a separate line, you use use a Box.
Box itemBox = Box.createVerticalBox();
itemBox.add(item1);
itemBox.add(item2);
add(itemBox);
Make:
item1 = new JTextField(10);
item2 = new JTextField(10);
that should solve problem with width of JTextField.
For beginning use GridLayout to display JTextField in one line. After that I strongly recomend using of MIG Layout http://www.migcalendar.com/miglayout/whitepaper.html.
put JLabel next to JTextField to describe what the user is expected to enter in the text field.
JLabel lbl = new JLabel("Description");
or you could also consider using of toolTipText:
item1.setToolTipText("This is description");
For making a form in Java Swing, I always recommend the FormLayout of JGoodies, which is designed to ... create forms. The links contains an example code snippet, which I just copy-pasted here to illustrate how easy it is:
public JComponent buildContent() {
FormLayout layout = new FormLayout(
"$label, $label-component-gap, [100dlu, pref]",
"p, $lg, p, $lg, p");
PanelBuilder builder = new PanelBuilder(layout);
builder.addLabel("&Title:", CC.xy(1, 1));
builder.add(titleField, CC.xy(3, 1));
builder.addLabel("&Author:", CC.xy(1, 3));
builder.add(auhtorField, CC.xy(3, 3));
builder.addLabel("&Price:", CC.xy(1, 5));
builder.add(priceField, CC.xy(3, 5));
return builder.getPanel();
}
Now for the description:
Use a label in front of the textfield to give a very short description
You can put a longer description in the textfield as suggested by #Alden. However, if the textfield is for short input, nobody will be able to read the description
You can use a tooltip (JComponent#setTooltipText) to put a longer description. Those tooltips also accept basic html which allows some formatting. Drawback of the tooltips is that the user of your application has to 'discover' that feature as there is no clear indication those are available
You can put a "help-icon" (like e.g. a question mark) after each text field (use a JButton with only an icon) where on click you show a dialog with a description (e.g. by using the JOptionPane class)
You can put one "help-icon" on each form which shows a dialog with a description for all fields.
Note for the dialog suggestion: I wouldn't make it a model one, allowing users to open the dialog and leave it open until they are finished filling in the form
Hello :) I am beginner in Java Swing and I can't google solution for my problem. I have a JPanel and want to add JTextField(s) dynamically after pressing a JButton. And how can I getText() from them later? My code, commented part isn't working properly.
Variable 'counter' counts how many fields I have in panel.
public class AppPanel extends JPanel {
private JTextField tfData[];
private JButton btAdd;
private int counter = 1;
public AppPanel() {
setLayout(null);
//tfData[counter] = new JTextField();
//tfData[counter-1].setBounds(20, 20, 250, 20);
//add(tfData[counter-1]);
btAdd = new JButton("Add field");
btAdd.setBounds(280, 20, 120, 20);
btAdd.addActionListener(new alAdd());
add(btAdd);
}
class alAdd implements ActionListener {
public void actionPerformed(ActionEvent e) {
//tfData[counter] = new JTextField();
//tfData[counter].setBounds(20, 20+20*counter, 250, 20);
//add(tfData[counter]);
++counter;
}
}
}
As you're already storing references to your text fields, just use this array to query the text of the text fields:
tfData[counter-1].getText();
will show you the text of the last added text field.
But you really should initialise your array before, otherwise you won't be able to add any items to it. I think that was your main problem as you commented out your adding-code.
// think about how many text fields you will need (here: 16)
private JTextField tfData[] = new tfData[16];
If you're using arrays, watch for not breaking over its bounds. But better use a list as proposed in the comments before as it grows dynamically and you won't have to deal with array bounds and can even skip counting (the list does that for you, too).
How to place components in layout on specific position.
Like I want to place 2 text boxes in first row, below 3 combo boxes.
But when I am trying to put they all appear in one line and I have used flowlayout. I have used the border as well. When I am resizing, the window sizes of the components are going out from border.
Can you suggest me some layouts to use and how to use it?
Here is my code :
topPanel=new JPanel();
topPanel.setLayout(new FlowLayout());
topPanel.setBorder(new TitledBorder(new EtchedBorder(), "Customer Data"));
CNameTextField = new JTextField (20); // create the Customer Name text field
CNameTextField.setEditable(true); // set editable text box
CIDLabel=new JLabel("Customer ID");
C_IDTextField = new JTextField (10);
C_IDTextField.setEditable(true); // set editable text box
topPanel.add(CNameTextField);
topPanel.add(C_IDTextField);
// Create and populate Room type combo box
roomTypeCombo = new JComboBox();
roomTypeCombo.addItem( "Budget($50)" );
// Create and populate Meal type combo box
mealCombo = new JComboBox();
mealCombo.addItem( "None" );
// Create and populate Days combo box
daysCombo = new JComboBox();
for(int i=0;i<31 ; i++) {
// populate combobox with days
daysCombo.addItem(i);
}
// Adding rest of the components to top panel
topPanel.add(roomTypeCombo);
topPanel.add(mealCombo);
topPanel.add(daysCombo);
Thanks.
The most specific type of layout is absolute positioning.
Warning: Absolute positioning should rarely, if ever, be used. There are many reasons why. Here is one: Absolute positioning (No layout manager) vs. absolute positioning in MiGlayout
- Thanks to user brimborium for the good idea of adding a warning.
That being said, here is how to use absolute positioning:
In your code above, instead of setting topPanel's layout to FlowLayout, set it to null.
topPanel.setLayout(null);
Later on in the code, right before you start adding components to topPanel, call the container's setBounds method:
someJComponent.setBounds(x-coord, y-coord, width, height);
So for example you created an instance of JComboBox() and named it roomTypeCombo, the following code shows how to absolutely position roomTypeCombo.
topPanel.setLayout(null);
// code...
roomTypeCombo = new JComboBox();
// code...
roomTypeCombo.setBounds(100, 100, 200, 50);
topPanel.add(roomTypeCombo);
The setBounds method, used above, has four parameters:
int x-coord - set roomTypeCombo's x-coordinate relative to
its parent, topPanel.
int y-coord - set roomTypeCombo's y-coordinate relative to its parent, topPanel.
int width - specify roomTypeCombo's width.
int height - specify roomTypeCombo's height.
I would just play around with the coordinates and see if you like anything that comes out of it. The worst thing that could happen is that you go back to using a layout, which is probably better than absolute positioning. Or you could implement your own layout manager, if you follow this hyperlink the first answer talks about implementing your own layout manager and has helpful links.
More information on absolute positioning
Try to change the layout.
http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html
You could go for a GridLayout with two lines (for example, there is some others possible combinations), with each line containing respectively 3 JComboBoxs, and two JTextFields.
Look carefully at the documentation and check out some examples easily reachable on the web.
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class SwingResizeJFrame {
public SwingResizeJFrame() {
JTextField TextField1 = new JTextField("firstTextField");
JTextField TextField2 = new JTextField("secondTextField");
JPanel firstPanel = new JPanel();
firstPanel.setLayout(new GridLayout(0, 2, 10, 10));
firstPanel.add(TextField1);
firstPanel.add(TextField2);
JComboBox comboBox1 = new JComboBox(new Object[]{"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
JComboBox comboBox2 = new JComboBox(new Object[]{"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
JComboBox comboBox3 = new JComboBox(new Object[]{"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
JPanel secondPanel = new JPanel();
secondPanel.setLayout(new GridLayout(0, 3, 10, 10));
secondPanel.add(comboBox1);
secondPanel.add(comboBox2);
secondPanel.add(comboBox3);
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(2, 1, 10, 10));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(firstPanel);
frame.add(secondPanel);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
SwingResizeJFrame demo = new SwingResizeJFrame();
}
});
}
}