Create Swing GUI Elements for each item in a Collection - JAVA - java

If I have a collection of objects:
public class Party {
LinkedList<Guy> partyList = new LinkedList<Guy>();
public void addGuy(Guy c) {
partyList.add(c);
}
}
And a tabbedPane:
public class CharWindow
{
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
try
{
CharWindow window = new CharWindow();
window.frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public CharWindow()
{
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize()
{
frame = new JFrame();
frame.setBounds(100, 100, 727, 549);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP);
frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
JTabbedPane PartyScreen = new JTabbedPane(SwingConstants.TOP);
tabbedPane.addTab("Party Screen", null, PartyScreen, null);
JTabbedPane tabbedPane_2 = new JTabbedPane(SwingConstants.TOP);
tabbedPane.addTab("New tab", null, tabbedPane_2, null);
JTabbedPane tabbedPane_3 = new JTabbedPane(SwingConstants.TOP);
tabbedPane.addTab("New tab", null, tabbedPane_3, null);
}
}
How would I add content to the tabbedPane "Party Screen" such that it displays a JLabel "Name" and a vertical JSeparator for each item in my LinkedList?

First, JTabbedPane is the widget that creates a new tab for each element panel. It is not the child of a tabbed interface. (Eg. JTabbedPane should hold a JPanel called partyScreen.)
JTabbedPane tabbedPanel = new JTabbedPane(); // holds all tabs
// this is how you add a tab:
JPanel somePanel = new JPanel();
tabbedPanel.addtab("Some Tab", somePanel);
// this is how you'd add your party screen
JPanel partyScreen = new JPanel();
tabbedPanel.addTab("Party Screen", partyScreen);
Remember, Java naming convention has a variable start with a lower case letter -- so partyScreen is preferred to PartyScreen.
Then iterate through each Guy object in Party and add the appropriate components. I have no idea why you're using a LinkedList instead of a List, but I'll assume you have a good reason not included in the code above.
// myParty is an instance of Party; I assume you have some sort of accessor to
// the partyList
LinkedList<Guy> partyList = myParty.getPartyList();
ListIterator<Guy> it = partyList.listIterator();
while( it.hasNext() ) {
Guy g = it.next();
partyScreen.add(new JLabel( g.getName() ));
partyScreen.add(new JSeparator() );
}
Depending on how you want it to be arranged in the partyScreen panel, you'll probably want to look into a Layout Manager.

Related

Create Scroll Bar for JFrame

Hi I am trying to create Scroll Bar for my JFrame. I created JPanel object and set components into JPanel. Then created a JScrollPane object for the panel. Then add the ScrollPane object to JFrame. I am not seeing any scrollbar. Also I am wondering if there is a option in JPanel that would resize the object inside Jpanel automatically according to the zoom level of the JPanel. Any help would be highly appreciated.
public class xmlottgui {
private JPanel Container;
private JFrame frmCreateXml;
private JTextField titlename;
private JLabel lbltitlename;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
xmlottgui window = new xmlottgui();
window.frmCreateXml.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public xmlottgui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
Container = new JPanel();
Container.setLayout(null);
//JScrollPane pane=new JScrollPane(Container,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
frmCreateXml = new JFrame();
frmCreateXml.setTitle("Create XML");
frmCreateXml.setBounds(100, 100, 1000, 1200);
frmCreateXml.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmCreateXml.getContentPane().setLayout(null);
//Create MenuBar
JMenuBar menuBar = new JMenuBar();
Container.add(menuBar);
JMenu mnFile = new JMenu("File");
menuBar.add(mnFile);
JMenuItem mntmImportFromCsv = new JMenuItem("Import From Excel File");
//Add menu item Exit
JMenuItem mntmexit = new JMenuItem("Exit");
mntmexit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
mnFile.add(mntmexit);
showform();
JScrollPane pane=new JScrollPane(Container,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pane.setLayout(null);
frmCreateXml.setContentPane(pane);
frmCreateXml.getContentPane().add(pane);
}
private void showform(){
titlename = new JTextField();
titlename.setBounds(164, 27, 749, 26);
Container.add(titlename);
titlename.setColumns(10);
lbltitlename = new JLabel("Title Name");
lbltitlename.setBackground(Color.GRAY);
lbltitlename.setBounds(22, 1000, 90, 16);
Container.add(lbltitlename);
}
This:
pane.setLayout(null);
Will completely disable your JScrollPane and prevent it from working as it will prevent the JScrollPane from displaying and manipulating its view port properly. JScrollPanes have there own very special layout manager, one you never want to muck with unless you are very clever and know what you're doing. As a general rule you should almost never use null layouts.
Also this is not correct:
frmCreateXml.setContentPane(pane);
frmCreateXml.getContentPane().add(pane);
You make pane the contentPane and then add pane to itself.
AND THIS is messing you up:
frmCreateXml.getContentPane().setLayout(null);
You will want to learn about and use the layout managers as it will make your life much easier.

How can I pass an ArrayList between two separate JTabbedPanes

I have a program utilizing JTabbedPane. On one pane I have a button that updates an arrayList of objects based on input from the same pane.
What I would like to happen is have the second pane update itself with the object information based on the arrayList in the first pane.
However, I am not sure how to pass the list between the panes. Is there some way to push the array to pane #2 when the update button on the first pane is pressed?
Here is the main file. Instantiating the two tabs
public class Assignment6 extends JApplet
{
private int APPLET_WIDTH = 650, APPLET_HEIGHT = 350;
private JTabbedPane tPane;
private StorePanel storePanel;
private PurchasePanel purchasePanel;
private ArrayList computerList;
public void init()
{
computerList = new ArrayList();
storePanel = new StorePanel(computerList, purchasePanel);
purchasePanel = new PurchasePanel(computerList);
tPane = new JTabbedPane();
tPane.addTab("Store Inventory", storePanel);
tPane.addTab("Customer Purchase", purchasePanel);
getContentPane().add(tPane);
setSize (APPLET_WIDTH, APPLET_HEIGHT); //set Applet size
}
}
The first panel instantiates a button listener that applies all of the logic to the array list "compList"
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//Add Computer to list
Computer comp = new Computer();
comp.setBrandName(brandField.getText());
comp.setPrice(Double.parseDouble(priceField.getText()));
comp.setMemory(Integer.parseInt(memoryField.getText()));
comp.setCPU(typeField.getText(), Integer.parseInt(speedField.getText()));
compList.add(comp);
}
stringField.setText(listString);
alertLabel.setText("Computer Added");
}
}
Here is the other pane. The for loop at the end is what I need to push the arrayList to. After it receives the list, it populates a box with a checkbox for each object in the list
public PurchasePanel(ArrayList compList)
{
west = new JPanel();
east = new JPanel();
totalField = new JTextField();
this.compList = compList;
setLayout(new GridLayout(0,2));
add(west);
add(east);
east.setLayout(new BorderLayout());
east.add(currentTotalLabel, BorderLayout.NORTH);
east.add(totalField, BorderLayout.CENTER);
west.setLayout( new BoxLayout(west, BoxLayout.Y_AXIS));
for(Object c : compList){
System.out.println("Made it");
NumberFormat fmt = NumberFormat.getCurrencyInstance();
String str = ("BrandName:" + (((Computer) c).getBrandName() +"CPU:" + (((Computer) c).getCPU() +"Memory:" + ((Computer) c).getMemory() + "M" +"Price:" + fmt.format(((Computer) c).getPrice()))));
JCheckBox chk = new JCheckBox(str);
west.add(chk);
}
}
}
You can use the same listener used to update the first ArrayList, to update the second pane. Something like:
jButton1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Update the first ArrayList
// Update the second pane
}

Removing item from JList with JButton, but won't refresh

I've searched and searched and found like 800 solutions, but none of 'em seems to work with my problem. I'm removing an item from a JList using a JButton, and then i want to refresh the GUI in the actionPerformed method. But things like repaint() or updateUI() hasn't helped. Here is my code:
public class Watchlist3 extends JPanel {
public static ArrayList<String> stocks = new ArrayList<String>();
JButton addStock, removeStock, viewStock, updaterInterval;
JLabel stocksAdded, currentInterval, listTitle;
JList stocklist;
JScrollPane listScroller;
public Watchlist3(JFrame frame) {
super(new BorderLayout());
//Adding some sample-components to the list
stocks.add("PLUG");
stocks.add("IDN");
stocks.add("GOOG");
//Create the components
addStock = new JButton("Add Stock");
addStock.setOpaque(true);
addStock.setBackground(Color.RED);
add(addStock, BorderLayout.LINE_START);
removeStock = new JButton("Remove Stock");
removeStock.setOpaque(true);
removeStock.setBackground(Color.YELLOW);
removeStock.putClientProperty("SENT_FRAME", frame);
add(removeStock, BorderLayout.LINE_END);
stocklist = new JList(stocks.toArray());
stocklist.setOpaque(true);
stocklist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
stocklist.setLayoutOrientation(JList.HORIZONTAL_WRAP);
add(listScroller = new JScrollPane(stocklist), BorderLayout.CENTER);
removeStock.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
int index = stocklist.getSelectedIndex();
if(index != -1){
stocks.remove(index);
System.out.println(stocks);
/* Here is where id like to refresh the gui! */
}
} catch (Exception ex) {}
}
});
}
private static void createAndShowGUI() {
//Create and set up the window.
final JFrame frame = new JFrame("Watchlist");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
Watchlist3 newContentPane = new Watchlist3(frame);
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Thanks in advance
You are removing from stocks List collection but not updating the JList model.
To update list model you need put this
// Add this item to the list and refresh
// convert stock list to Object array becuase seListData accept Object[]
Object[] array = stocks.toArray(new Object[stocks.size()]);
stocklist.setListData(array);
listScroller.revalidate();
listScroller.repaint();

JList putting text into specific textfields based on how many are clicked

I'm currently creating a soundboard application where the person is going to click one of the items in my JList and its going to set the name of the next available text field as what was just clicked then i'm going to add buttons later.
For example, if my first click is the 2nd item in the JList it will go into the first JTextfield and my second click will go into the second JTextfield.
The program will have around 100 items in the JList by the time the app is done.
Also there is a problem that when the top one and a different JList item is clicked the top one will display first. Not necessarily a problem if I can get the problem fully functional but it makes it feel a little wonky.
package com.leagueoflegends.soundboard;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
public class Soundboard implements ListSelectionListener {
static JList<Object> list;
String[] text = { "hello", "testing1", "testing2" };
Icon icon;
JLabel pictureLabel;
JPanel insidePanel;
JTextField inlineText;
JTextField field[] = new JTextField[6];
public Soundboard() {
JFrame f = new JFrame("soundboard!");
JPanel masterPanel = new JPanel(new BorderLayout());
//icon = new ImageIcon(getClass().getResource("Tray.png"));
//pictureLabel = new JLabel(icon);
list = new JList<Object>(text); // data has type Object[]
list.setSelectionModel(new DefaultListSelectionModel(){
public void setSelectionInterval(int index0, int index1){
if(super.isSelectedIndex(index0)){
super.removeSelectionInterval(index0,index1);
}else{
super.addSelectionInterval(index0,index1);
}
}
});
list.setLayoutOrientation(JList.VERTICAL_WRAP);
list.setVisibleRowCount(-1);
list.addListSelectionListener(this);
JScrollPane listScroller = new JScrollPane(list);
listScroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
listScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
listScroller.setPreferredSize(new Dimension(100, 60));
// listScroller.setSize(new Dimension(250, 60));
JPanel smallPanel = new JPanel(new GridLayout(2, 3));
// smallPanel.setBorder(BorderFactory.createLineBorder(Color.red));
for (int i = 0; i <= 5; i++) {
insidePanel = new JPanel(new BorderLayout());
insidePanel.setBorder(BorderFactory.createLineBorder(Color.black));
field[i] = new JTextField();
field[i].setEditable(false);
field[i].setHorizontalAlignment(JTextField.CENTER);
insidePanel.add(field[i], BorderLayout.PAGE_START);
smallPanel.add(insidePanel);
}
masterPanel.add(smallPanel);
masterPanel.add(pictureLabel, BorderLayout.PAGE_START);
masterPanel.add(listScroller, BorderLayout.WEST);
f.add(masterPanel);
f.pack();
f.setSize(1000, 800);
f.setMinimumSize(new Dimension(400, 350));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
for (int i = 0; i < text.length; i++) {
if (list.getSelectedIndex() == i) {
field[0].setText(text[i]);
}
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Soundboard();
}
});
}
If i understood your question correct than you have to provide a custom list model to your list. You can initialize your JList with this custom list model.
The entries of your list model hold a reference to
an appropriate textfield instance. So each time you select an entry of the list you
have access to your custom list item you can manipulate the text of the associated textfield.
The custom list model must implement the ListModel interface or extend AbstractListModel class.
There are many nice tutorials have a look here:
Swing/UsingaCustomDataModel.htm">http://www.java2s.com/Tutorial/Java/0240_Swing/UsingaCustomDataModel.htm
Hope it helps.

JTabbedPane addTab in wrapper method not working

As part of my Diploma in Software Dev we have to create a Java GUI to manage a Soccer League. My group has produced numerous JPanels that in the click-through prototype we put into JTabbedPane. This worked fine up until now where I'm moving them into separate files and into a MVC layout.
I'm using a window class to hold the top level JFrame and menubar and adding in the tabbed panes to that. This works fine in the constructor but when I remove them from the constructor and try to add them from the Bootstrap via the Window.attachTabbedPanel(String name, JPanel panel) it doesn't display but querying tabbedPane.getTabCount() display an incrementing number of tabs.
Here's a stripped back set of code:
The Bootstrap file:
public class Bootstrap {
private Window mainWindow;
public Bootstrap() {
//Window class is our containing JFrame and JMenuBar
mainWindow = new Window();
//Load up our view classes
TestTab tab1 = new TestTab();
TestTab tab2 = new TestTab();
//Attach them
mainWindow.attachTabbedPanel("Tab1", tab1.getScreen());
mainWindow.attachTabbedPanel("Tab2", tab2.getScreen());
} // Bootstrap()
public gui.Window getWindow(){
return mainWindow;
}
} // Bootstrap
This is called by the Main file:
public class Main {
public static void main(String[] args) {
Bootstrap RunMVC = new Bootstrap();
gui.Window mainWindow = RunMVC.getWindow();
mainWindow.run();
} // main()
} // Main
The problem starts here at the Window class, I've added in a In Constructor tab to check I haven't stuffed up the tabbedPane but it works fine at that point.
public class Window {
private JFrame frame;
private JMenuBar menuBarMain;
private JMenu mnFile;
private JTabbedPane tabbedPane;
private int count;
/**
* Create the application.
*/
public Window() {
//Build the frame
frame = new JFrame();
frame.setBounds(100, 100, 1280, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new CardLayout(0, 0));
//End Build frame
TestTab conTab = new TestTab();
//Add the tabbed pane to hold the top level screens
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
frame.getContentPane().add(tabbedPane, "name_1");
tabbedPane.addTab("In Consructor", conTab.getScreen());
count = 1;
}
public void attachTabbedPanel(String name, JPanel panel){
System.out.println("Window: adding Jpanel name: "+name);
System.out.println("panel is a: "+panel);
tabbedPane.addTab(name, panel);
tabbedPane.updateUI();
System.out.println("Number of tabs: "+tabbedPane.getTabCount());
System.out.println("Last Tab .isEnabledAt() "+tabbedPane.isEnabledAt(count++));
tabbedPane.updateUI();
}
/**
* Launch the window.
*/
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Window window = new Window();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
And lastly the Panel:
public class TestTab {
private JPanel screen;
private JLabel lblSeason;
private JButton btnEdit;
private JLabel lblRounds;
public JPanel getScreen() {
return screen;
}
/**
* Initialize the contents of the frame.
*/
public TestTab() {
screen = new JPanel();
screen.setLayout(new MigLayout("", "[8%,right][10%,left][8%,right][10%,left][grow][50%]", "[][][grow]"));
lblSeason = new JLabel("Test");
screen.add(lblSeason, "flowx,cell 0 0");
btnEdit = new JButton("Edit Test");
screen.add(btnEdit, "cell 5 0,alignx right");
lblRounds = new JLabel("More Testing");
screen.add(lblRounds, "cell 0 1,alignx left");
}
}
Your error is here:
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Window window = new Window();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
You are using new instance of window instead of using created earlier, try to use this code
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
updateUI() does not do what you think it does. It should never be called directly - it is called from the superclass constructor to allow the Swing look and feel delegate to initialize itself.
Eliminating the call to updateUI() may solve your problem; or if the tabbed pane is already on screen, you may need to force a repaint/revalidate - the incantation for that is invalidate(); revalidate(); repaint();.

Categories

Resources