For example I have a Table that I want to get text that's in the first column and store it in an ArrayList.
Java Tables often use the TableModel interface for storage.
You can get the a particular value via:
myJTable.getModel().getValueAt(rowIndex, columnIndex);
More on that: Sun's Swing Table Tutorial
public static void main(String[] args)
{
try
{
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = frame.getContentPane();
cp.setLayout(new FlowLayout());
final JTable tbl = new JTable(new String[][]{{"c1r1", "c2r1"}, {"c1r2", "c2r2"}}, new String[]{"col 1", "col 2"});
cp.add(tbl);
cp.add(new JButton(new AbstractAction("click")
{
#Override
public void actionPerformed(ActionEvent e)
{
List<String> colValues = new ArrayList<String>();
for (int i = 0; i < tbl.getRowCount(); i++)
colValues.add((String) tbl.getValueAt(0, i));
JOptionPane.showMessageDialog(frame, colValues.toString());
}
}));
frame.pack();
frame.setVisible(true);
}
catch (Throwable e)
{
e.printStackTrace();
}
}
You need to go through the JTable's TableModel, accessible through the getModel() method. That has all the information you need.
Related
I'm using sortable columns for my JTable:
table.setAutoCreateRowSorter(true);
The issue is that after the user click on a column header there's no way to remove the arrow. Even If I delete all the rows in the table.
I tried to do the opposite but it didn't work:
table.setAutoCreateRowSorter(false);
The fact the arrow is not removed seem to be a painting issue. Calling table.getTableHeader().repaint() seems to make the arrow go away.
Full example:
public class JTableSortRestore {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
runGui();
});
}
private static void runGui() {
JFrame frame = new JFrame("");
frame.setLayout(new BorderLayout());
DefaultTableModel model = new DefaultTableModel();
model.addColumn("Col");
model.addRow(new String[] { "BBB" });
model.addRow(new String[] { "AAA" });
model.addRow(new String[] { "CCC" });
JTable table = new JTable(model);
table.setAutoCreateRowSorter(true);
frame.add(new JScrollPane(table));
JButton restoreButton = new JButton("Restore sorting");
restoreButton.addActionListener(e -> {
table.setAutoCreateRowSorter(false);
table.setAutoCreateRowSorter(true);
table.getTableHeader().repaint();
});
frame.add(restoreButton, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
I have a database with tables. I passed the name of the tables into the buttons. When you click, you need a table with fields and filling to appear. The problem is that I have a new table added every time I click on the button.
Can someone please say me how to do it? Thanks in advance!
public class App extends JPanel {
static List<FieldElement> fields = new ArrayList<>();
static List<Map<String, Object>> data = new ArrayList<>();
static JTable jTable = new JTable();
public static void createGUI() throws SQLException {
TableContent tableContent = new TableContent();
JFrame frame = new JFrame();
MetadataHelper databaseMetadata = new MetadataHelper();
List<ButtonElement> elements = databaseMetadata.showTables();
JPanel panel = new JPanel();
JPanel buttons = new JPanel(new GridLayout(0, 1));
for (ButtonElement buttonElements : elements) {
JButton jButton = new JButton(buttonElements.getTablesInMigrateSchema());
buttons.add(jButton);
jButton.addActionListener(new ActionListener() {
#SneakyThrows
#Override
public void actionPerformed(ActionEvent e) {
fields = tableContent.getDatabaseMetadata().showFields(buttonElements.getTablesInMigrateSchema());
data = tableContent.getDatabaseMetadata().selectAll(buttonElements.getTablesInMigrateSchema());
Object[][] objectRows = data.stream().map(m -> m.values().toArray()).toArray(Object[][]::new);
jTable = new JTable(objectRows, fields.toArray());
panel.add(new JScrollPane(jTable));
frame.revalidate();
frame.repaint();
}
});
}
panel.add(buttons, BorderLayout.EAST);
frame.add(panel);
frame.setTitle("SwingSandbox");
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#SneakyThrows
public void run() {
JFrame.setDefaultLookAndFeelDecorated(true);
createGUI();
}
});
}
}
One easy possibility is to store the JScrollPane in a variable (which holds your table that you want to remove):
static JTable jTable = new JTable();
static JScrollPane jScrollPane;
And then in your actionPerformed method:
public void actionPerformed(ActionEvent e) {
...
if (jScrollPane != null) {
panel.remove(jScrollPane);
}
jTable = new JTable(objectRows, fields.toArray());
jScrollPane = new JScrollPane(jTable);
panel.add(jScrollPane);
frame.revalidate();
frame.repaint();
}
This is my first time creating a Gui and I'm stumped on how to create interactions.
I'm trying to implement a single selection mode when the combobox is on single, and multiple when it's placed on multiple. I placed them on the multi line comment.
Any ideas?
//Interactions
//When “Single” is selected then the JList changes so only one item
can be selected.
//When “Multiple” is selected, the JList changes so multiple items can
be selected
//When a country, or multiple countries, is selected the JLabel
changes to reflect the new selections
public class GuiTest {
public static String[] Countries = {"Africa", "Haiti", "USA", "Poland", "Russia", "Canada", "Mexico", "Cuba"};
public static String[] Selection = {"Single", "Multiple"};
JPanel p = new JPanel();
JButton b = new JButton("Testing");
JComboBox jc = new JComboBox(Selection);
JList jl = new JList(Countries);
private static void constructGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame();
frame.setTitle("Countries Selection");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// add a JLabel that says Welcome
JLabel label = new JLabel("Selected Items:");
frame.add(label);
frame.pack();
JComboBox jc = new JComboBox(Selection);
frame.add(jc);
frame.pack();
frame.setVisible(true);
JList jl = new JList(Countries);
frame.add(jl);
frame.pack();
JComponent panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(new JLabel("Choose Selection Mode:"));
panel.add(jc);
frame.add(panel, BorderLayout.NORTH);
frame.add(jl, BorderLayout.WEST);
frame.add(label, BorderLayout.SOUTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
constructGUI();
}
});
}
}
you should start adding the modes to the ComboBox:
comboBoxCategoria.addItem("Single",0);
comboBoxCategoria.addItem("Multiple",1);
then add a ActionListener to your ComboBox to modify the list selection mode
jc.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(jc.getSelectedItem().equals("Single")){
jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}else{//must equals
jl.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
}
});
finally add a MouseListener on the list to detect changes on the list selections and change the JLabel to reflect the new selections
jl.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
label.setText(list.getSelectedValuesList().toString());
}
});
edit: you should also add a KeyListener to update the label since the selection can be changed via arrow keys
jl.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
label.setText(list.getSelectedValuesList().toString());
}
});
It would be something like this:
jc.addActionListener((evt) -> {
if ("Single".equals(jc.getSelectedItem())) {
jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
int[] sel = jl.getSelectedIndices();
if (sel != null && sel.length > 1) {
jl.setSelectedIndex(sel[0]);
}
} else {
jl.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
});
jl.addListSelectionListener((evt) -> {
StringBuilder buf = new StringBuilder();
for (Object o: jl.getSelectedValuesList()) {
if (buf.length() > 0) {
buf.append(", ");
}
buf.append(o);
}
label.setText(buf.toString());
});
jc.setSelectedItem("Single");
public static void table2() {
Object num[] = new Object[1];
for (int q = 0; q < MyDto.userList.size(); q++) {
try {
//ImageIcon i2 = new ImageIcon(new ImageIcon(MyDto.userList.get(q).getMyImg()).getImage()
// .getScaledInstance(150, 120, Image.SCALE_SMOOTH));
ImageIcon i2 = new ImageIcon("/Users/junseok/Desktop/1.png");
JLabel lbImage1 = new JLabel(i2);
lbImage1.setIcon(i2);
num[0] = lbImage1;
model2.addRow(num);
System.out.println(num[0].toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
why doesnt show image? why write only toString()??
why write only toString()??
The default renderer just invokes the toString() method of the object in the TableModel.
why doesnt show image?
You need to add an Icon to the TableModel (not a JLabel). Then you need to tell the table the Icon is stored in the column so the table can choose the appropriate renderer to paint the Icon.
This is done by overriding the getColumnClass(...) method of the TableModel:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableIcon extends JPanel
{
public TableIcon()
{
Icon aboutIcon = new ImageIcon("about16.gif");
Icon addIcon = new ImageIcon("add16.gif");
Icon copyIcon = new ImageIcon("copy16.gif");
String[] columnNames = {"Picture", "Description"};
Object[][] data =
{
{aboutIcon, "About"},
{addIcon, "Add"},
{copyIcon, "Copy"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
#Override
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
};
JTable table = new JTable( model );
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Table Icon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableIcon());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
How to add a Back button on top of JTable ? I tried but no luck.
public class viewMovie extends JPanel{
static JFrame frame = new JFrame("View Movie");
JTable table;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
createAndShowGui();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
static void createAndShowGui() throws Exception {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new viewMovie());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public viewMovie() throws Exception
{
String sql="Select * from movie";
DatabaseConnection db = new DatabaseConnection();
Connection conn =db.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmt= rs.getMetaData();
int c= rsmt.getColumnCount();
Vector column= new Vector(c);
for(int i=1;i<=c;i++)
{
column.add(rsmt.getColumnName(i));
}
Vector data = new Vector();
Vector row=new Vector();
while(rs.next())
{
row=new Vector(c);
for(int i=1;i<=c;i++)
{
row.add(rs.getString(i));
}
data.add(row);
}
JButton back= new JButton("Back");
JPanel topPanel = new JPanel(new GridLayout(1, 0, 3, 3));
topPanel.add(back);
JPanel panel= new JPanel();
table=new JTable(data,column);
JScrollPane jsp = new JScrollPane(table);
panel.setLayout(new BorderLayout());
panel.add(jsp,BorderLayout.CENTER);
frame.setContentPane(panel);
frame.setVisible(true);
}
}
This is the output I get.
You're forgetting one line of code, the line that adds the topPanel to the panel JPanel:
panel.add(topPanel, BorderLayout.PAGE_START);
Side note: for future questions, you will want to make your code compilable and runnable by us, meaning get rid of unnecessary dependencies, such as database. For your code above, the database stuff could be replaced by:
JPanel panel = new JPanel();
Integer[][] data = { { 1, 2, 3 }, { 4, 5, 6 } };
String[] column = { "A", "B", "C" };
table = new JTable(data, column);
But actually since it is just a simple layout question, even the JTable is not necessary.