Is it possible to have a child element larger than its parent? - java

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?

Related

Clean the window in swing

I have a group of jRadioButton that I created,
each button has an action listener that creates a JTable in a separate window.
I want that when I press another button, the frame will be cleaned and then the other JTable to be performed,
ButtonGroup group = new ButtonGroup();
JRadioButton[] jRadioButton = new JRadioButton[5];
for (int i = 0; i < 5; i++) {
jRadioButton[i] = new JRadioButton("machine "+i);
jRadioButton[i].setBounds(x, y, width, height);// x, y, width, height are place parameters
group.add(jRadioButton[i]);
frame.getContentPane().add(jRadioButton[i]);
frame.update(frame.getGraphics());//update the frame and add the buttons
}
let's say, I pressed machine 1 and a table popped up in a different window, now when I press machine 2 and a different table will pop up I want to clear the new window before the second table is shown.
So my question is, is it possible to clean a window and if yes how?
If the only difference is JTable you can just change the table's model with theTable.setModel(properJRadioButtonDependentModel).
If you have more controls you can either use a CardLayout swapping panels (for each JRadioButton instance you can create a panel and swap them)
OR
remove all controls using removeAll() method of container, add new controls and call
container.revalidate();
container.repaint();
the table creation
public void createMachineTable(int row) {
model = new DefaultTableModel(col, row);
table = new JTable(model) {
/**
*
*/
#Override
public boolean isCellEditable(int rows, int columns) {
if (columns == 0)
return false;//left side uneditable
else
return true;//right side editable
}
};
pane = new JScrollPane(table);// the new window of te table
getContentPane().add(pane);
setVisible(true);
setSize(500, 600);
getContentPane().setLayout(new FlowLayout());
setDefaultCloseOperation(1);
}
now, when pressing a different button, the following levels will be applied
pane.getViewport().remove( table );
createMachineTable(rowsNumer);
the table will be deleted and a new one will be created.

Vertical JPanel manual positioning: which layout?

Given my requirements:
Single vertical column of JPanels.
Set the vertical location* of the JPanel without using the properties of a sibling.
Component position and size are fixed when the frame is resized.
Keep other layout aspects automatic (such as preferred size calculation), as much as possible
(*) Location: I mean location as in Component.setLocation(x, y).
is there a solution which is obvious, and if this is GridBagLayout, how to do this?
Details:
I want to put components vertically in a column container (like a vertical Box) by specifying their vertical location only. What is the best way to do this without loosing the other benefits of a layout such as BoxLayout?
In a vertical Box, setting the vertical position of a component must be done using a filler, or by adjusting the size of the component just above, there is no such possibility like:
panel.setLocation(getLocation().x, y)
On the other hand using a no layout container puts on me the task manage:
The initial size of the component
The container resizing events.
Here the solution of null layout is recommended, here this is a custom one, and here this is GridBagLaout. Also MIGLayout appears to be universal one (but I'd prefer no adding another library to my project).
I have written the following program for someone who was also looking for the same requirements.
Note: Make sure to add the first element to 0 position because there will be no more components and no position will be available other than 0, 2nd to 0 or 1, 3rd to 0 or 1 or 2 and so on
public class VerticalList extends JFrame {
JPanel pnl = null;
TextField tf = new TextField(10);
Box center = Box.createVerticalBox();
JScrollPane jsp = new JScrollPane(center);
JPanel ctrl = new JPanel(new FlowLayout());
JButton send = new JButton("Send");
public VerticalList() {
jsp.setAutoscrolls(true);
ctrl.add(send);
ctrl.add(new JLabel("Position:"));
ctrl.add(tf);
Container cnt = getContentPane();
cnt.add(jsp, BorderLayout.CENTER);
cnt.add(ctrl, BorderLayout.SOUTH);
send.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pnl = new JPanel(new FlowLayout());
pnl.setBorder(BorderFactory.createLineBorder(Color.red));
pnl.add(new JLabel("Added to Position: "+tf.getText()));
pnl.setMaximumSize(new Dimension(Integer.MAX_VALUE, (int)pnl.getPreferredSize().getHeight()));
try{
int index = Integer.parseInt(tf.getText());
center.add(pnl, index);
}catch(Exception ex){
JOptionPane.showMessageDialog(null, "Please Provide a Valid position", "Position Error", JOptionPane.ERROR_MESSAGE);
}
validate();
}
});
setPreferredSize(new Dimension(300, 300));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
pack();
}
public static void main(String[] args) {
new VerticalList();
}
}

Java Applet gridlayout issue

im having a little issue with my code. I have created a gridlayout of 5,1,0,0. I have a textfield, 3 buttons and a label where the result analysis of whatever the user had input is displayed at the bottom. Now the results can come on multiple lines depending on how big words are in the sentence, my problem is when multiple lines of results are displayed, the layout of my program changes and i dont know how to keep it the same but just the label or Applet window itself resize if need be?
public class assignment_tauqeer_abbasi extends JApplet implements ActionListener {
JTextArea textInput; // User Input.
JLabel wordCountLabel; // To display number of words.
public void init() {
// This code from here is the customisation of the Applet, this includes background colour, text colour, text back ground colour, labels and buttons
setBackground(Color.black);
getContentPane().setBackground(Color.black);
textInput = new JTextArea();
textInput.setBackground(Color.white);
JPanel south = new JPanel();
south.setBackground(Color.darkGray);
south.setLayout( new GridLayout(5,1,0,0) );
/* Creating Analyze and Reset buttons */
JButton countButton = new JButton("Analyze");
countButton.addActionListener(this);
south.add(countButton);
JButton resetButton = new JButton("Reset");
resetButton.addActionListener(this);
south.add(resetButton);
JButton fileButton = new JButton("Analyze Text File");
fileButton.addActionListener(this);
south.add(fileButton);
/* Labels telling the user what to do or what the program is outputting */
wordCountLabel = new JLabel(" No. of words:");
wordCountLabel.setBackground(Color.black);
wordCountLabel.setForeground(Color.red);
wordCountLabel.setOpaque(true);
south.add(wordCountLabel);
/* Border for Applet. */
getContentPane().setLayout( new BorderLayout(2,2) );
/* Scroll bar for the text area where the user will input the text they wish to analyse. */
JScrollPane scroller = new JScrollPane( textInput );
getContentPane().add(scroller, BorderLayout.CENTER);
getContentPane().add(south, BorderLayout.SOUTH);
} // end init();
public Insets getInsets() {
// Border size around edges.
return new Insets(2,2,2,2);
}
// end of Applet customisation
This is my code for the layout. Any help would be apprecited!
A GridLayout will size every cell according to the content of the largest cell. Consider using a different layout, or a combination of layouts instead.
The gridLayout that you have used would possibly complicate the five contents that you have used. Try using flow Layout instead this would automatically make space for the new contents that are being entered.

Display an ArrayList<Object> in JTextArea of another class

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.

Adding text next to a textfield to describe what data the user is expected to enter into it

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

Categories

Resources