I'm developping a Java application.
I created this interface with MockupScreens.
Please look at these pictures.
At first time, there's only one element, the user have to enter informations (title and description) then he starts adding elements as he needs.
He can edit elemnt infomrations at any time.
He can too delete or change the order of this elements ...
How can I do to create something like the pictures up?????
Thanks in advance.
Best regards,
Ali.
I know these parts in Java Swing.
My problem is how to insert this block of buttons dynamically.
I get an idea, I must put JButtons on a JPanel then manipulate the JPanel by adding, removing and reodering...
So a Grid Layout will be efficient to add each panel after each one, but thinking on reordering the order will be so hard ...
Any suggestions please. :)
After searching, I get an idea:
Let us put these JButtons in a JPanel called btnsUnit, then manipulate it by adding, removing and reodering... So a GridLayout will be efficient to add each JPanel after each one ..
Thats why I created a new JPanel which will contain an unknown number of ListbtnsUnit JPanel, I fixed 10 as the max number.
I'm just doing these steps when you reply me. I didn't arrived to add btnsUnit JPanel in ListbtnsUnit JPanel.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
public class setupDeviceList extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
setupDeviceList frame = new setupDeviceList();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public setupDeviceList() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 742, 335);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
final JPanel ListbtnsUnit = new JPanel();
ListbtnsUnit.setBackground(Color.RED);
ListbtnsUnit.setBounds(55, 56, 243, 191);
contentPane.add(ListbtnsUnit);
ListbtnsUnit.setLayout(new GridLayout(10, 0));
final JButton btnAdd = new JButton("Add");
btnAdd.setBounds(161, 11, 56, 23);
btnAdd.setVisible(true);
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
final JPanel btnsUnit = new JPanel();
btnsUnit.setBounds(343, 71, 243, 147);
contentPane.add(btnsUnit);
btnsUnit.setBackground(Color.ORANGE);
btnsUnit.setLayout(null);
btnsUnit.add(btnAdd);
ListbtnsUnit.add(btnsUnit);
ListbtnsUnit.revalidate();
ListbtnsUnit.repaint();
}
});
}
}
Please can you help me in this code.
I need just the first push to go on.
but thinking on reordering the order will be so hard ...
In your ActionListener for the button:
use getSource() method to get the button that was clicked
use the getParent() method of the button to find the panel the button belongs to
use the getParent() method of the buttons panel to find its parent panel
use the getComponents method to get an Array of all the button panels. Then loop through the Array to find the index of the panel you are search for.
once you find the index you increase of decrease the index, then you can add the panel back to its parent panel at the new index.
then you revalidate() and repaint() the parent panel to display the panel in its new location.
Nice images :-)
You need these parts, if you want to do this in Swing:
javax.swing.JButton (the several buttons)
javax.swing.JTextField (the one line text input component)
javax.swing.JTextArea (the multi-line text input component)
javax.swing.JLabel (labels for your input fields)
javax.swing.JPanel (a container to group several components together, like your lines of buttons, or the editing components at the right)
javax.swing.JFrame (the window for all together)
javax.swing.Action (actions to be performed when a button is clicked - they also can contain an icon and/or text for the button)
Look at these, start to code, and then come back if you have concrete problems. Good luck!
I think you are using a wrong idiom here. What you are trying to accomplish is usually done using JList (scrollable list of items). This way you need just one set of operations such as reorder, add and delete, next to the JList. Operations should operate on selected item in JList (otherwise they should be disabled)
Your interface may look sort of like
The idiom you're currently using is mostly done on web pages. Desktop UIs, (especially Swing) are much richer.
You can find more about how to use JList at http://download.oracle.com/javase/tutorial/uiswing/components/list.html
Related
I am writing a small program just for personal use to double check strategies on a mobile based game. I created a Board class and frame and whatnot, then I created a new Panel class in my package (I use Eclipse). I figured it would be as simple as creating the two and implementing the Panel and adding it to the main frame of the Board class. Alas, I was mistaken.
TubePanel - my secondary panel
package ballSort;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerListModel;
import javax.swing.JLabel;
public class TubePanel extends JPanel {
/**
* Create the panel.
*/
public TubePanel() {
setBackground(new Color(47, 79, 79));
setBounds(10, 10, 30, 40);
}
}
**This is an excerpt from my main Board class.... **
panel_1 = new JPanel();
panel_1.setBounds(118, 164, 726, 466);
frame.getContentPane().add(panel_1);
JButton btnNewButton_1 = new JButton("X");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.dispose();
}
});
btnNewButton_1.setFont(new Font("Tahoma", Font.PLAIN, 89));
btnNewButton_1.setBounds(10, 122, 85, 124);
frame.getContentPane().add(btnNewButton_1);
}
public void Create(int tubes) {
TubePanel tube = new TubePanel();
panel_1.add(tube);
System.out.println(tube);
System.out.println(panel_1);
}
Am I the idiot here? This should've worked, as far as I'm concerned, but clearly I know not the ways of the Java. [Only been coding java for 4 years.] Anyway the problem is that it doesn't show the tubePanel.
It doesn't give any errors either so I had to use Sysout to see if there was anything wrong with it and panel_1 for a comparison...
ballSort.TubePanel[,10,10,30x40,**invalid**,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
javax.swing.JPanel[,118,164,726x466,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
Aside from the invalid (to which I tried to follow it to its root, I couldn't figure it out) there's nothing different from panel_1 compared to tube.
Any help is much appreciated.
Refer to the lesson entitled Laying Out Components Within a Container from trail Creating a GUI With JFC/Swing which is part of Oracle's Java tutorials.
The default layout of the content pane of a JFrame is BorderLayout. When you add a component to the content pane, it gets added to the center area of the BorderLayout. The center area (and all other areas) of BorderLayout can only contain a single component. So when you add two components to the center area, only one will be displayed. Refer to method add(Component, Object) in class java.awt.Container
So study the layout managers and decide which is suitable.
I want do design a simple login format and in order to do so I want two JTextFields for Username/Password and a Login Button. The Login button is display as expected but when I add the JTextField, nothing shows in my JFrame. Would be nice if someone could help a beginner out...
Here's my code (I know it's ugly but this is just a "code sketch"):
package bucketlistpackage;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GameFrame extends JFrame {
public GameFrame(String title) {
super(title); //sets title of frame
startFrame(); //sets details of main frame
final Container logincont = getContentPane(); //creates content pane
JFrame loginframe = new JFrame();
usernameField(loginframe);
loginButton(loginframe);
logincont.add(loginframe);
}
private void usernameField(JFrame loginframe) {
JTextField usernameF = new JTextField("Username", 1);
usernameF.setBounds(50, 50, 50, 20);
loginframe.add(usernameF);
usernameF.setVisible(true);
}
private void startFrame() {
this.setSize(1000, 1000);
this.setVisible(true);
}
private void loginButton(Container cont) {
JButton loginB = new loginButton();
loginB.setSize(300, 150);
loginB.setText("Login");
cont.add(loginB);
}
}
The problem lies on how you are adding component to one another in your case.
You are adding a JFrame to a Container, when in all case it should be the other way around.
The other problem is that you are not using Layouts to manage the components positions on the JFrame.
Another problem as well is that you are not refreshing the windows after adding all the stuff on it.
A bit of a resume on how Java works with native UIs:
Java creates a new thread for the UI. So if you open the debugger you will see AWT threads as well as the main threads and others. This means that you have to manage this in a correct way, because after the application starts SWING and the functions you determine for reactions will lay the ground on how it will behave. Your main thread will die, but the visual threads will keep active.
If you are just starting to program I would encourage you to practice a bit more native java language before moving to SWING or AWT. This libraries can be really painful and tricky to use.
The other thing is SWING library follows a hierarchy for the components:
JFrame > JPanels > Components
In your code you have already worked with all of them but in a disorganized way. JFrame is the main application window, where the graphics will be displayed (can also be a Canvas or whatever class you want to use for that matter). JPanels are organizers, you can use different layouts to organize whatever is inside it. And finally the Components are well... everything! A component can be a JTextField, but it can also be a JPanel, or JButton.
The idea with SWING is to create multiple Panels and organize the end components inside them, using the help of the different layouts to see whats the best approach to make them attractive in many different window sizes.
Finally, if you are using Eclipse, there is a plugin called WindowBuilder which might help you. I don't recommend you using it if you are very new to Java since it will make you depend a lot on it instead of learning how to actually code with SWING.
Hope this helps!!!
Btw, to fix the code above I would do something like this:
public GameFrame(String title) {
super(title); //sets title of frame
startFrame(); //sets details of main frame
final Container logincont = getContentPane(); //creates content pane
logincont.setLayout(new BorderLayout());
usernameField(logincont, BorderLayout.NORTH);
loginButton(logincont, BorderLayout.CENTER);
this.revalidate();
this.repaint();
}
private void usernameField(Container loginframe, String direction) {
JTextField usernameF = new JTextField("Username");
// usernameF.setBounds(50, 50, 50, 20);
loginframe.add(usernameF, direction);
usernameF.setVisible(true);
}
private void startFrame() {
this.setSize(1000, 1000);
this.setVisible(true);
}
private void loginButton(Container cont, String direction) {
JButton loginB = new JButton();
loginB.setSize(300, 150);
loginB.setText("Login");
cont.add(loginB, direction);
}
I'm trying to get two components,
frame.getContentPane().setLayout(new MigLayout("", "[53px,grow][57px][grow]", "[23px][][][]"));
JTextPane itemTitle = new JTextPane();
frame.getContentPane().add(itemTitle,"cell 0 4,alignx left,aligny top");
itemTitle.setVisible(true);
itemTitle.setMinimumSize(new Dimension(50, 50));
List choices = new List();
frame.add(choices, "cell 0 4,alignx left,aligny top");
choices.setVisible(true);
to be in the same place, but all the happens is this:
The two components highlighted at itemTitle and choices.
My aim is to have the buttons above set one "setVisible" to true and the other to false. They would never both be true. How can I get two components in one cell at the same time? It also puts my above buttons out of place and I'm not too sure why. I put above the important code referring to the two components, I could put the full GUI code if you requested.
I found this: Fill Entire Cell With Two Components Using MigLayout However it is over years old and to be honest, I don't understand the solution.
I'm sort of learning as I go, I've never used MigLayout before. Should I be using a different layout?
Thanks for any help
to be in the same place... My aim is to have the buttons above set one "setVisible" to true and the other to false. They would never both be true
Then you should be using a JPanel that contains those two components. Then you use a Card Layout on that panel and use the CardLayout to determine which component is visible at any given time. This panel can be added to the panel using the MigLayout just like any other component.
List choices = new List();
Looks to me like you are using an AWT component. You should be using JList for a Swing application.
Should I be using a different layout?
No, stick with MigLayout. You have chosen the right layout manager.
I advice you to invest some time into learning this manager; create couple
of smaller practical examples, learn the numerous constraints that this
manager provides.
It also puts my above buttons out of place and I'm not too sure why.
MigLayout is a grid-based layout manager. (Its most important mode is.)
The gap between the New and Open buttons is created because the
highlighted components and the New button form a column. The column width
is determined by the width of the largest cell. To bypass this, we can
use the split constraint. (Often used in combination with span constraint.)
In my example I use this technique to center two buttons above the
currently visible label.
If we are not sure about something in the layout, we can use the
debug layout constraint which paints the lines of the grid and bounds
of the components.
frame.getContentPane().setLayout(new MigLayout("", "[53px,grow][57px][grow]", "[23px][][][]"));
Do not set bounds in pixels. You are not utilizing of one of the
most important advantages of this manager -- independence of resolution and
DPI. Bounds in pixels are not portable. A 3px gap between buttons looks OK on a smaller screen but is not acceptable on a larger one.
MigLayout provides several options to choose from including related and unrelated gaps, logical pixels, points, or centimeters.
itemTitle.setMinimumSize(new Dimension(50, 50));
Setting a minimum size of a component is usually not necessary. But if we need to
do it, we have the wmin and wmax constraints. This should be done by the
layout manager, not by code outside of it. The set(Minimum|Maximum|Preferred)size
methods should be avoided. (With poorer managers, one cannot do without them, however.)
And again, setting dimensions in pixels is not optimal.
Now we get to the solution. MigLayout has hidemode constraint to deal
with your requirement. There are four hide modes. I assume that we need
the hidemode 3, in which all invisible components do not participate in the
layout.
package com.zetcode;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class HidingComponentsEx extends JFrame {
private ArrayList<JLabel> lbls;
private int itemVisible = 0;
public HidingComponentsEx() {
initUI();
}
private void initUI() {
createLabels();
JButton prevBtn = new JButton("Previous");
prevBtn.addActionListener(new PrevAction());
JButton nextBtn = new JButton("Next");
nextBtn.addActionListener(new NextAction());
JPanel pnl = new JPanel(new MigLayout("ins dialog"));
pnl.add(prevBtn, "split 2, center");
pnl.add(nextBtn, "wrap");
for (JLabel lbl : lbls) {
pnl.add(lbl, "cell 0 1, w 250lp, h 100lp, hidemode 3");
}
add(pnl);
pack();
setTitle("MigLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void createLabels() {
lbls = new ArrayList<>();
lbls.add(createLabel("North Sea"));
lbls.add(createLabel("Ionian Sea"));
lbls.add(createLabel("Norwegian Sea"));
lbls.add(createLabel("Bering Sea"));
lbls.add(createLabel("Dead Sea"));
lbls.get(itemVisible).setVisible(true);
}
private class NextAction extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
lbls.get(itemVisible).setVisible(false);
itemVisible++;
if (itemVisible > 4) {
itemVisible = 0;
}
lbls.get(itemVisible).setVisible(true);
}
}
private class PrevAction extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
lbls.get(itemVisible).setVisible(false);
itemVisible--;
if (itemVisible < 0) {
itemVisible = 4;
}
lbls.get(itemVisible).setVisible(true);
}
}
private JLabel createLabel(String text) {
JLabel lbl = new JLabel(text, JLabel.CENTER);
lbl.setVisible(false);
lbl.setBorder(BorderFactory.createEtchedBorder());
return lbl;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
HidingComponentsEx ex = new HidingComponentsEx();
ex.setVisible(true);
}
});
}
}
Our example has two buttons and five labels. The buttons dynamically change their
visibility.
I have a JComboBox that, when clicked, should update the contents of a JLabel. I'm currently using a mouseListener to detect when the user clicks on the JComboBox like so:
myComboBox.getEditor().getEditorComponent().addMouseListener(
new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
updateMyJLabel(evt);
}
});
I have no trouble actually updating the JLabel outside of this snippet. I previously had it set up so that I could change the contents of the JComboBox and then click a JButton to update the JLabel, and it worked fine. However, it quickly became tedious to click the button every time I need to update the JLabel. But when I add myComboBox to the layout after using the above code, the code never actually executes. I also tried putting a print statement above the call to updateMyJLabel, but even that didn't do anything, the console was beautifully, frustratingly blank.
This is only my second day of attempting ui development, so sorry if this is a dumb question. I read quite a number of other questions here on SO, and some people have said not to use a mouseListener on a JComboBox, others have said code like this worked perfectly for them, so I'm a bit confused as to why this isn't working.
Any suggestions and help are greatly appreciated.
See JComboBox.addItemListener(ItemListener). It works reliably on mouse or keyboard selection.
Adding mouse listeners to JComboBox is always going to be a problem. It tends to be implemented by PL&Fs as a container of other components. (Of course a PL&F may choose to do something else, breaking lots of dodgy code.) Mouse events behave very peculiarly, bubbling up to the parent contain iff there are no mouse listeners on the current component. Adding a mouse listener changes the behaviour of a component.
(I'd always put an #Override when attempting to override a method. Amazing how common and confusing it is to get it wrong. Also MouseAdapter is a bit nasty as you may use it as a MouseListener or MouseMotionListener.)
I'm not entirely sure what you are trying to do. Probably adding a listener to the combo box model would make most sense. If you want to reliably add a mouse listener, you'd probably need to go for a "glass pane" hack.
here is an example for you
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main {
public static void main(String args[]) {
JFrame frame = new JFrame("Demo Frame/SuRu");
Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT));
final JLabel jLabel = new JLabel();
final JComboBox box = new JComboBox();
box.addItem("");
box.addItem("Item 1");
box.addItem("Item 2");
box.addItem("Item 3");
box.addItem("Item 4");
box.addItem("Item 5");
box.addItem("Item 6");
box.addItem("Item 7");
box.addItem("Item 8");
box.addItem("Item 9");
box.addItem("Item 10");
contentPane.add(new JLabel("Select Here: "));
contentPane.add(box);
contentPane.add(new JLabel("Seleced Item: "));
contentPane.add(jLabel);
box.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent arg0) {
jLabel.setText(box.getSelectedItem().toString());
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(200, 200, 400, 100);
frame.setVisible(true);
}
}
I am developing a Java Desktop Application. In the GUI, I want that user can add as many toolbars dynamically as he wants. To implement this, the following are the things that I have done already:
Have taken a mainPanel and set its layout as BorderLayout
Then taken a topPanel and added it to the mainPanel's BorderLayout.NORTH
set the topPanel's layout as BoxLayout
Then taken 5 panels named toolbar1Panel, toolbar2Panel, ....
Afterthat, have added one toolbar to each of the toolbarPanel created in the previous steps.
Have added only one toolbarPanel i.e toolbar1Panel on the topPanel
Now there is a button named "Add" on the first toolbar which is added on the "toolbar1Panel" which in turn is added to the topPanel.
Now I have implemented the "actionPerformed()" method of the above "Add" button as follows:
// to add second toolbar Panel to the topPanel dynamically
topPanel.add(toolbar2Panel);
But the problem is that it is not working. Means there is no toolbar added to the topPanel.
Is there anything which I am missing.
The code is Netbeans Generated so I think it would only add mess for others, that's why I haven't pasted any code here.
After adding another toolbar to the BoxLayout, you may need to (re|in)?validate the panel.
I've done this repeatedly but I can't understand the logic behind the 3 or so method calls; so I just try them until I hit on the one that works:
topPanel.validate();
topPanel.invalidate();
topPanel.revalidate();
topPanel.layout();
(at least) one of those should force your GUI to re-calculate its layout, making the north panel larger and thus showing the 2nd (and successive) toolbar(s) you've added.
Without specifying the layout for the top panel, it might be assuming the incorrect one.
Adding two toolbar panels to it might just be replacing the first with the second, or ignoring the second.
Just for testing set the topPanel's layout to FlowLayout and try again.
I think you are trying to do too much before testing. the way I would approach this is to start with something very simple, for example one panel, one static label. When that appears as you expect add a toolbar with a menu item. Does that work. Then incrmentally add the pieces.
Quite likely you'll have problems with a simple case and can then figure it out, or you'll have a simple case to post here.
Alterntively, as starting point pinck some working example from the net. Cut it down and then build up to your case.
Does it help ?
Is it what you want to achieve ?
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
public class AddingToolbars {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
AddingToolbars me = new AddingToolbars();
me.initGui();
}
});
}
private JPanel topPanel;
private JPanel mainPanel;
private JFrame frame;
private void initGui() {
frame = new JFrame();
mainPanel = new JPanel(new BorderLayout());
frame.setContentPane(mainPanel);
topPanel = new JPanel();
BoxLayout bLayout = new BoxLayout(topPanel,BoxLayout.Y_AXIS);
topPanel.setLayout(bLayout);
mainPanel.add(topPanel,BorderLayout.NORTH);
JButton addButton = new JButton("Add toolbar");
mainPanel.add(addButton,BorderLayout.CENTER);
addButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
addNewToolBar();
}
});
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
protected void addNewToolBar() {
JToolBar tb = new JToolBar();
tb.add(new JButton("b1"));
tb.add(new JButton("b2"));
tb.add(new JButton("b3"));
topPanel.add(tb);
mainPanel.validate();
}
}