Java Swing using JList with an ArrayList<> - java

Basically, I've got a CD Library that holds instances of a CD ArrayList<>, I've then got a people ArrayList<> that can "borrow" CD's... from that CD's are added to an available, or unavailable list.
public CDStore(String storeNme) {
storeName = storeNme;
discsArray = new ArrayList<CD>();
peopleArray = new ArrayList<Person>();
}
By using a JList, I'm trying to make the elements of the list equal the instances of CD.
So... item1 in the list would be the CD at index 0, item 2 = index 1 and so on....
String[] entries = ??????????????????;
JList listOfCD = new JList(entries);
listOfCD.setVisibleRowCount(4);
JScrollPane listPane = new JScrollPane(listOfCD);
JTextField valueField = new JTextField("None", 7);
Thankyou.

Your CDStore could implement the interface ListModel. Than you can use the CDStore as a model for your JList.
CDStore store = new CDStore("Store");
// add some CDs
JList listOfCD = new JList(store);
listOfCD.setVisibleRowCount(4);
JScrollPane listPane = new JScrollPane(listOfCD);
JTextField valueField = new JTextField("None", 7);
Here is example implementation of CDStore implements ListModel. Everytime the discsArray changes you should call the method fireContentsChanged.
public class CDStore implements ListModel {
private String storeName;
private List<CD> discsArray;
private List<Person> peopleArray;
public CDStore(String storeNme) {
storeName = storeNme;
discsArray = new ArrayList<CD>();
peopleArray = new ArrayList<Person>();
}
//your methods
//ListModel
private List<ListDataListener> listener = new ArrayList<ListDataListener>();
public void addListDataListener(ListDataListener l) {
listener.add(l);
}
public void removeListDataListener(ListDataListener l) {
listener.remove(l);
}
protected void fireContentsChanged() {
for (ListDataListener l : listener) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, discsArray.size()-1));
}
}
public Object getElementAt(int index) {
return discsArray.get(index);
}
public int getSize() {
return discsArray.size()
}
}

If you have a method to retrieve CD name, let's call it getCDName(),
you can try
String[] entries = new String[discsArray.length];
int index = 0;
for (CD cd: discsArray) {
entries[index++] = cd.getCDName();
}
This should fill in your entries array.

Related

How to use a variable which is used in an ActionListener?

as you can see in the picture I'm setting up a table which shows all files from a specific path (later I'll implement a filter for pdf files only). First, all files are simultaneously shown, but I want to see each single file of the path during the build up of the table. So I've changed it to a array list, but there a two errors which I really couldn't resolve...
Hope that you can help me ;-)
class FileModel extends AbstractTableModel implements FilenameFilter {
String titles[] = new String[] { "Path" };
Class<?> types[] = new Class[] { String.class, String.class };
private List<Object[]> data = new ArrayList<>();
public FileModel() {
this("C:\\");
}
public FileModel(String dir) {
File pwd = new File(dir);
setFileStats(pwd);
}
// Implement the methods of the TableModel interface we're interested
// in. Only getRowCount(), getColumnCount() and getValueAt() are
// required. The other methods tailor the look of the table.
#Override
public int getRowCount() {
return this.data.size();
}
#Override
public int getColumnCount() {
return this.titles.length;
}
#Override
public String getColumnName(int c) {
return this.titles[c];
}
#Override
public Class<?> getColumnClass(int c) {
return this.types[c];
}
#Override
public Object getValueAt(int r, int c) {
return this.data.get(r)[c];
}
// Our own method for setting/changing the current directory
// being displayed. This method fills the data set with file info
// from the given directory. It also fires an update event so this
// method could also be called after the table is on display.
public void setFileStats(File dir) {
System.out.println("SET MY DIR " + dir);
this.data = new ArrayList<>();
this.fireTableDataChanged();
String files[] = dir.list();
this.data = new Object[files.length][this.titles.length]; **// Here error #1**
for (int i = 0; i < files.length; i++) {
File tmp = new File(files[i]);
this.data[i][0] = tmp.getAbsolutePath(); **// Here error #2**
}
this.fireTableDataChanged();
}
#Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return false;
}
}
Here's the code of the JFrame windows:
public class FileFrame extends JFrame {
protected FileModel fileModel = new FileModel();
{
this.setSize(500, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JTable FileTable = new JTable(this.fileModel);
TableRowSorter<TableModel> TableRowSorter = new TableRowSorter<TableModel>(this.fileModel);
FileTable.setRowSorter(TableRowSorter);
FileTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
FileTable.setColumnSelectionAllowed(true);
FileTable.setDefaultRenderer(Number.class, new BigRenderer(1000));
JScrollPane JScrollPane = new JScrollPane(FileTable);
getContentPane().add(JScrollPane, BorderLayout.CENTER);
}
public static void main(String args[]) {
final FileFrame FileFrame = new FileFrame();
// Create menubar
JMenuBar menubar = new JMenuBar();
// Create JMenu object
JMenu menu = new JMenu("File");
// Create JMenuItem object
final JMenuItem openItem = new JMenuItem("Open");
JMenuItem exititem = new JMenuItem("Exit");
// Add JMenuItem to JMenu
menu.add(openItem);
menu.add(exititem);
// Add menu to menubar
menubar.add(menu);
// Add menubar to dialog
FileFrame.setJMenuBar(menubar);
// Show dialog
FileFrame.setVisible(true);
// Integrate ActionListener as anonymous class
openItem.addActionListener(new java.awt.event.ActionListener() {
public File savedPath;
public final JFileChooser FileChooser = new JFileChooser("C:\\");
// Initialize actionPerformed
#Override
public void actionPerformed(ActionEvent e) {
// Generate choose file
this.FileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
this.FileChooser.setDialogTitle("Selection of pdf directory");
this.FileChooser.setAcceptAllFileFilterUsed(false);
// Set the text
this.FileChooser.setApproveButtonText("Open directory");
// Set the tool tip
this.FileChooser.setApproveButtonToolTipText("Select pdf directory ");
if (this.savedPath != null)
this.FileChooser.setCurrentDirectory(this.savedPath);
int returnVal = this.FileChooser.showOpenDialog(openItem);
if (returnVal == JFileChooser.APPROVE_OPTION) {
this.savedPath = this.FileChooser.getSelectedFile();
FileFrame.fileModel.setFileStats(this.savedPath);
}
}
});
// Integrate ActionListener as anonymous class
exititem.addActionListener(new java.awt.event.ActionListener() {
// Initialize actionPerformed
#Override
public void actionPerformed(ActionEvent e) {
// Close program
System.exit(0);
}
});
}
}
The problem is you are trying to access data as though its an array
private List<Object[]> data = new ArrayList<>();
...
this.data = new Object[files.length][this.titles.length];
this.data[i][0] = tmp.getAbsolutePath();
But data is actually a List<Object[]>
So you might want to do
//data.add(new Object[files.length][this.titles.length]);
data.add(new Object[files.length]); // can only be one dimensional
and
((Object[])data.get(i))[0] = tmp.getAbsolutePath();
instead
See more on how to use Lists at The List Interface
UPDATE
Change your model code to this
String files[] = dir.list();
for (int i = 0; i < files.length; i++) {
File tmp = new File(files[i]);
data.add(new Object[] { tmp.getAbsolutePath()}) ;
}
All you need to do is add a new Object[] to the list (inside the loop) with just the file path, since that seems to be all you need. Don't add one before.

Adding items to an already existing jlist from another class

I have a jList (named JList1) created using the Desing mode from NetBeans IDE, and I want to add items to that list using a secondary class which parses a big xml list and gets the data from it. My problem is that I dont really understand how to do this, I already tried a lot of different codes, tried with a model too, but cant get it right. I am new to java (and programming too), and I dont understand if I do something like
String[] ar = {"one", "two", "three"};
JList Jlist1 = new JList(ar);
this created a new jList instead of using my already created one, no ?
created using the Desing mode from NetBeans IDE,
maybe not good idea to be prisonier of code generated by
add a new Item to DefaultListModel
and I want to add items to that list using a secondary class which
parses a big xml list and gets the data from it.
sounds like as you have an issue with Concurency in Swing, updates to the already visible Swing GUI must be done on EDT
use SwingWorker#publish() for long and hard job (which parses a big xml list and gets the data from it.)
for example, add a new Item to DefaultListModel
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Testing extends JFrame {
private static final long serialVersionUID = 1L;
private DefaultListModel listModel = new DefaultListModel();
private JList list = new JList(listModel);
private int currentSelectedRow = 0;
private int xX = 0;
public Testing() {
setLocation(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
for (int x = 0; x < 9; x++) {
listModel.addElement("" + x);
xX++;
}
JScrollPane sp = new JScrollPane(list);
add(sp, BorderLayout.CENTER);
JButton btn1 = new JButton("Reset Model CastingModel");
add(btn1, BorderLayout.NORTH);
btn1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
list.clearSelection();
DefaultListModel model = (DefaultListModel) list.getModel();
model.removeAllElements();
// note Swing GUI by default to freeze if is removed more that
// 999 elemets from the JList or its underlaying XxxListModel,
// to use repeatly Actions from SwingTimer on short period
for (int x = 0; x < 9; x++) {
model.addElement("" + (x + xX));
xX++;
}
list.setModel(model);
}
});
JButton btn2 = new JButton("Reset Model directly from Model");
add(btn2, BorderLayout.SOUTH);
btn2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
list.clearSelection();
listModel.removeAllElements();
for (int x = 0; x < 9; x++) {
listModel.addElement("" + (x + xX));
xX++;
}
}
});
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Testing().setVisible(true);
}
});
}
}
String[] ar = {"one", "two", "three"};
JList Jlist1 = new JList(ar);
The constructor you are using is as follows
/**
* Constructs a <code>JList</code> that displays the elements in
* the specified array. This constructor creates a read-only model
* for the given array, and then delegates to the constructor that
* takes a {#code ListModel}.
* <p>
* Attempts to pass a {#code null} value to this method results in
* undefined behavior and, most likely, exceptions. The created model
* references the given array directly. Attempts to modify the array
* after constructing the list results in undefined behavior.
*
* #param listData the array of Objects to be loaded into the data model,
* {#code non-null}
*/
public JList(final E[] listData)
{
this (
new AbstractListModel<E>() {
public int getSize() { return listData.length; }
public E getElementAt(int i) { return listData[i]; }
}
);
}
So you need to have your array which you are passing as an argument to the constructor final. Also do make use of generics.
final String[] ar = {"one", "two", "three"};
JList<String> Jlist1 = new JList<String>(ar);
Lastly since you are using new keyword it is bound to create new object. Just make your original list point to this new JList object created using your array. Mind you have to make it final and cannot be changed later.

How to add data to the GXT Grid properly?

I have a webapp in which I need to get some data from the file and fill to the table. Here is the code of the page with this table:
public class Rules extends ContentPanel{
private final ServerManagementAsync serverManagementSvc = GWT.create(ServerManagement.class);
private ArrayList<PropertyItem> propslist;
private ArrayList<PropertyItem> itemArrayList;
private EditorGrid<PropertyItem> grid;
public Rules(final String customerId){
setLayout(new FlowLayout(10));
List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig column = new ColumnConfig();
column.setId("name");
column.setHeader("Name");
column.setWidth(220);
TextField<String> text = new TextField<String>();
text.setAllowBlank(false);
column.setEditor(new CellEditor(text));
configs.add(column);
column = new ColumnConfig();
column.setId("type");
column.setHeader("Type");
column.setWidth(220);
TextField<String> typeText = new TextField<String>();
typeText.setAllowBlank(false);
column.setEditor(new CellEditor(typeText));
configs.add(column);
column = new ColumnConfig();
column.setId("value");
column.setHeader("Value");
column.setWidth(220);
configs.add(column);
final ListStore<PropertyItem> store = new ListStore<PropertyItem>();
propslist = getPropslist(customerId);
for (PropertyItem propertyItem: propslist){
store.insert(propertyItem, 0);
}
ColumnModel cm = new ColumnModel(configs);
setHeading("Settings");
setFrame(true);
setWidth(600);
setLayout(new FitLayout());
grid = new EditorGrid<PropertyItem>(store, cm);
grid.setAutoExpandColumn("name");
grid.setBorders(true);
add(grid);
ToolBar toolBar = new ToolBar();
setTopComponent(toolBar);
setButtonAlign(Style.HorizontalAlignment.RIGHT);
addButton(new Button("Refresh", new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
store.insert(getPropslist(customerId), 5);
}
}));
addButton(new Button("Add", new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
store.commitChanges();
}
}));
}
public ArrayList<PropertyItem> getPropslist(String customerId){
itemArrayList = new ArrayList<PropertyItem>();
AsyncCallback<ArrayList<PropertyItem>> callback = new AsyncCallback<ArrayList<PropertyItem>>() {
#Override
public void onFailure(Throwable throwable) {
}
#Override
public void onSuccess(ArrayList<PropertyItem> propertyItems) {
itemArrayList = propertyItems;
Window.alert("read successful");
}
}
};
serverManagementSvc.getProperties(customerId, callback);
return itemArrayList;
}
}
When I run my app I See only columns names and no data in the cells(and no cells of course). As the example I used this one: Ext GWT 2.2.6 Explorer(Grid)
I don't understand what could cause such proplem. What can be the reason of this?
Because your propsList is being populated Asynchronously the grid is being rendered before the server call returns.
To fix this first make the store a private property like the grid
Next, move the code that populates your store:
for (PropertyItem propertyItem: propslist){
store.insert(propertyItem, 0);
}
into the onSuccess Method of your callback.
Lastly, you may also need to call :
grid.reconfigure(grid.getStore(), grid.getColumnModel());
Just to get the Grid to render again.

Enable drop just for specific targets in Swing

I'm trying to implement drag & drop in java with two JList instances.
The basic flow works fine. However, when I'm dragging a string from one list, I want to restrict the drop target only for the second list.
I noticed that when I'm dragging a string from one list to my desktop so it creates a file containing this string.
Is there any way to avoid such situations?
public class SampleDnD extends JFrame{
public static void main(String[] args) {
new SampleDnD();
}
/**
* new form of frame sample contain 2 JLists with drag enabled.
*/
public SampleDnD(){
JList l1 = new JList();
JList l2 = new JList();
JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
JScrollPane jScrollPane2 = new javax.swing.JScrollPane();
DefaultListModel listModel1 = new DefaultListModel();
DefaultListModel listModel2 = new DefaultListModel();
String[] list1 = new String[]{"1","3","5","7","9"};
String [] list2 = new String[]{"0","2","4","6","8"};
for(int index=0;index<list1.length;index++){
listModel1.add(index, list1[index]);
listModel2.add(index, list2[index]);
}
l1.setModel(listModel1);
l2.setModel(listModel2);
l1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
l2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
l1.setDropMode(DropMode.INSERT);
l1.setDragEnabled(true);
l2.setDragEnabled(true);
l1.setTransferHandler(new ListTransferHandler());
l2.setDropMode(DropMode.INSERT);
l2.setTransferHandler(new ListTransferHandler());
jScrollPane1.setViewportView(l1);
jScrollPane2.setViewportView(l2);
Container cp = getContentPane();
cp.setLayout(new BoxLayout(cp,BoxLayout.Y_AXIS));
setPreferredSize(new Dimension(800,500));
getContentPane().add(jScrollPane1);
getContentPane().add(jScrollPane2);
setVisible(true);
pack();
}
public class ListTransferHandler extends TransferHandler {
/**
* We only support importing strings.
*/
public boolean canImport(TransferHandler.TransferSupport info) {
// Check for String flavor
if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return false;
}
return true;
}
/**
* Bundle up the selected items in a single list for export.
*
*/
protected Transferable createTransferable(JComponent c) {
JList list = (JList)c;
String value = (String)list.getSelectedValue();
return new StringSelection(value);
}
/**
* We support only move actions.
*/
public int getSourceActions(JComponent c) {
return TransferHandler.MOVE;
}
/**
* Perform the actual import. This demo only supports drag and drop.
*/
public boolean importData(TransferHandler.TransferSupport info) {
if (!info.isDrop()) {
return false;
}
JList list = (JList)info.getComponent();
DefaultListModel listModel = (DefaultListModel)list.getModel();
JList.DropLocation dl = (JList.DropLocation)info.getDropLocation();
int index = dl.getIndex();
boolean insert = dl.isInsert();
// Get the string that is being dropped.
Transferable t = info.getTransferable();
String data;
try {
data = (String)t.getTransferData(DataFlavor.stringFlavor);
}
catch (Exception e) { return false; }
if (insert) {
listModel.add(index++, data);
} else {
// If the items go beyond the end of the current
// list, add them in.
if (index < listModel.getSize()) {
listModel.set(index++, data);
} else {
listModel.add(index++, data);
}
}
return true;
}
/**
* Remove the items moved from the list.
*/
protected void exportDone(JComponent c, Transferable data, int action) {
JList source = (JList)c;
DefaultListModel listModel = (DefaultListModel)source.getModel();
if(action == TransferHandler.MOVE)
{
listModel.remove(source.getSelectedIndex());
}
}
}
}
A little late, but maybe helpful for somebody else:
You need to create your own DatFlavor, that will only be accepted by your own application.
DataFlavor myObjectDataFlavor = new DataFlavor(MyObject.class, "java/MyObject");
Pass this one instead of a default DataFlavor.javaFileListFlavor or DataFlavor.stringFlavor. Your class MyObject is a Pojo containing only a class variable of type String or an integer or whatever you need.

How to remove a row from the Cell Table

At first I used the Grid.
After creating a new version of the GWT, I want to replace the Grid on the CellTable.
Check out the javadoc for details. My example is like the one you'll find there (just a little extended):
public void onModuleLoad() {
final CellTable<Row> table = new CellTable<Row>();
TextColumn<Row> firstColumn = new TextColumn<Starter.Row>() {
#Override
public String getValue(Row object) {
return object.firstColumn;
}
};
table.addColumn(firstColumn, "header one");
TextColumn<Row> secondColumn = new TextColumn<Starter.Row>() {
#Override
public String getValue(Row object) {
return object.secondColumn;
}
};
table.addColumn(secondColumn, "header two");
TextColumn<Row> thirdColumn = new TextColumn<Starter.Row>() {
#Override
public String getValue(Row object) {
return object.thirdColumn;
}
};
table.addColumn(thirdColumn, "header three");
table.setRowCount(getList().size());
final ListDataProvider<Row> dataProvider = new ListDataProvider<Starter.Row>(getList());
dataProvider.addDataDisplay(table);
final SingleSelectionModel<Row> selectionModel = new SingleSelectionModel<Starter.Row>();
table.setSelectionModel(selectionModel);
Button btn = new Button("delete entry");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Row selected = selectionModel.getSelectedObject();
if (selected != null) {
dataProvider.getList().remove(selected);
}
}
});
RootPanel.get().add(table);
RootPanel.get().add(btn);
}
private class Row {
private String firstColumn;
private String secondColumn;
private String thirdColumn;
public Row(String firstColumn, String secondColumn, String thirdColumn) {
this.firstColumn = firstColumn;
this.secondColumn = secondColumn;
this.thirdColumn = thirdColumn;
}
}
private LinkedList<Row> getList() {
LinkedList<Row> list = new LinkedList<Row>();
list.add(new Row("first", "entry", "foo"));
list.add(new Row("second", "entry", "foo"));
list.add(new Row("third", "entry", "foo"));
list.add(new Row("fourth", "entry", "foo"));
return list;
}
Or you can just run the cycle like that
#UiHandler("combo")
public void onChange(ChangeEvent e) {
textBoxes.clear();
searchFields.clear();
while(resultsTable.getColumnCount()!=0) {
resultsTable.removeColumn(0);
}
resultsTable.redraw();
Where resultsTable is a CellTable
CellTable as part of new DataPresentationWidgets used just to display data. So you should delete according member from list of data which CellTable using to display.

Categories