Scroll a JScrollPane to a specific row on a JTable [duplicate] - java

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
JTable Scrolling to a specified row index
I have a JTable and I programmatically need to select a row by using this code:
myTable.setRowSelectionInterval(i, j);
(where i and j are valid row and column numbers respectively).
The problem is, when you jump to a row, the JScrollPane does not move.
In this case, the table is quite long, and often the "selected row" is not visible on the screen, so the user has to stay scrolling up/down manually to find it. I would like to know how I can make the JScrollPane automatically jump to the specific location of the row.
Edit: Found this one liner which can do it:
table.scrollRectToVisible(table.getCellRect(row,0, true));

just extends post by #Eng.Fouad +1, no works as I exactly expected (with kind help by StanislavL from another Java Swing forum)
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.DefaultTableModel;
public class TableSelectionGood implements ListSelectionListener {
private JTable[] tables;
private boolean ignore = false;
public TableSelectionGood() {
Object[][] data1 = new Object[100][5];
Object[][] data2 = new Object[50][5];
Object[][] data3 = new Object[50][5];
for (int i = 0; i < data1.length; i++) {
data1[i][0] = "Company # " + (i + 1);
for (int j = 1; j < data1[i].length; j++) {
data1[i][j] = "" + (i + 1) + ", " + j;
}
}
for (int i = 0; i < data2.length; i++) {
data2[i][0] = "Company # " + ((i * 2) + 1);
for (int j = 1; j < data2[i].length; j++) {
data2[i][j] = "" + ((i * 2) + 1) + ", " + j;
}
}
for (int i = 0; i < data3.length; i++) {
data3[i][0] = "Company # " + (i * 2);
for (int j = 1; j < data3[i].length; j++) {
data3[i][j] = "" + (i * 2) + ", " + j;
}
}
String[] headers = {"Col 1", "Col 2", "Col 3", "Col 4", "Col 5"};
DefaultTableModel model1 = new DefaultTableModel(data1, headers);
DefaultTableModel model2 = new DefaultTableModel(data2, headers);
DefaultTableModel model3 = new DefaultTableModel(data3, headers);
final JTable jTable1 = new JTable(model1);
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane sp1 = new JScrollPane();
sp1.setPreferredSize(new Dimension(600, 200));
sp1.setViewportView(jTable1);
final JTable jTable2 = new JTable(model2);
jTable2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane sp2 = new JScrollPane();
sp2.setPreferredSize(new Dimension(600, 200));
sp2.setViewportView(jTable2);
final JTable jTable3 = new JTable(model3);
jTable3.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final JScrollPane sp3 = new JScrollPane();
sp3.setPreferredSize(new Dimension(600, 200));
sp3.setViewportView(jTable3);
TableSelectionGood tableSelection = new TableSelectionGood(jTable1, jTable2, jTable3);
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(3, 0, 10, 10));
panel1.add(sp1);
panel1.add(sp2);
panel1.add(sp3);
JFrame frame = new JFrame("tableSelection");
frame.add(panel1);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public TableSelectionGood(JTable... tables) {
for (JTable table : tables) {
table.getSelectionModel().addListSelectionListener(this);
}
this.tables = tables;
}
private JTable getTable(Object model) {
for (JTable table : tables) {
if (table.getSelectionModel() == model) {
return table;
}
}
return null;
}
private void changeSelection(JTable table, String rowKey) {
int col = table.convertColumnIndexToView(0);
for (int row = table.getRowCount(); --row >= 0;) {
if (rowKey.equals(table.getValueAt(row, col))) {
table.changeSelection(row, col, false, false);
return;
}
}
table.clearSelection();
}
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() || ignore) {
return;
}
ignore = true;
try {
JTable table = getTable(e.getSource());
int row = table.getSelectedRow();
String rowKey = table.getValueAt(row, table.convertColumnIndexToView(0)).toString();
for (JTable t : tables) {
if (t == table) {
continue;
}
changeSelection(t, rowKey);
JViewport viewport = (JViewport) t.getParent();
Rectangle rect = t.getCellRect(t.getSelectedRow(), 0, true);
Rectangle r2 = viewport.getVisibleRect();
t.scrollRectToVisible(new Rectangle(rect.x, rect.y, (int) r2.getWidth(), (int) r2.getHeight()));
System.out.println(new Rectangle(viewport.getExtentSize()).contains(rect));
}
} finally {
ignore = false;
}
}
public static void main(String[] args) {
TableSelectionGood tableSelection = new TableSelectionGood();
}
}

I used this in my old project:
public static void scrollToVisible(JTable table, int rowIndex, int vColIndex)
{
if (!(table.getParent() instanceof JViewport)) return;
JViewport viewport = (JViewport)table.getParent();
Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
Point pt = viewport.getViewPosition();
rect.setLocation(rect.x-pt.x, rect.y-pt.y);
viewport.scrollRectToVisible(rect);
}
Reference: http://www.exampledepot.com/egs/javax.swing.table/Vis.html

Related

JavaSwing add multiple JTable to JFrame

I am working on java swing application.I have to browse multiple CSV data files and display them into JFrame using JTable.I am trying to add multiple(non static) JTable into JFrame.All (N) JTable i want to include inside a JSrollPane.At this moment i can display only 1 table to JScrollPane.
Thanks in advance!
if (e.getSource() == jbtreadbrowsefile) {
try {
for(int k=0;k<file_locations.length;k++) {
String currentLocation=file_locations[k];
inputList = new ArrayList();
File inputF = new File(currentLocation);
InputStream inputFS = new FileInputStream(inputF);
BufferedReader br = new BufferedReader(new InputStreamReader(inputFS));
inputList = br.lines().collect(Collectors.toList());
br.close();
int count = inputList.size();
if(count>0)
{
data = new String[count - 1][8];
for (int i = 0; i < count - 1; i++) {
String[] arrOfStr = inputList.get(i + 1).toString().split(",");
String test1= arrOfStr[0];
String test2= arrOfStr[1];
String test3= arrOfStr[2];
String test4 = arrOfStr[3];
String test5= arrOfStr[4];
String test6= arrOfStr[5];
String test7= arrOfStr[6];
data[i][0] = "" + (i + 1);
data[i][1] = test1;
data[i][2] = test2;
data[i][3] = test3;
data[i][4] = test4;
data[i][5] = test5;
data[i][6] = test6;
data[i][7] = test7;
}
j = new JTable(data, columnNames);
TableColumnModel tcm = j.getColumnModel();
tcm.getColumn(0).setPreferredWidth(40);
tcm.getColumn(1).setPreferredWidth(220);
tcm.getColumn(2).setPreferredWidth(120);
tcm.getColumn(3).setPreferredWidth(80);
tcm.getColumn(4).setPreferredWidth(80);
tcm.getColumn(5).setPreferredWidth(80);
tcm.getColumn(6).setPreferredWidth(80);
tcm.getColumn(7).setPreferredWidth(80);
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
j.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
for (int i = 0; i < j.getRowCount(); i++) {
j.setRowHeight(i, 20);
}
j.getTableHeader().setFont(new Font("SansSerif", Font.BOLD, 15));
j.getTableHeader().setReorderingAllowed(false);
j.repaint();
JScrollPane sp = new JScrollPane(j);
sp.setBounds(10, 200, 780, 440);
add(sp);
}
else
{
JOptionPane.showMessageDialog(this,"No Data Found in the File");
}
}
JScrollPane sp = new JScrollPane(j);
sp.setBounds(10, 200, 780, 440);
add(sp);
Don't use setBounds(). It is the job of the layout manager to determine the size/location of a component.
At this moment i can display only 1 table to JScrollPane.
Correct. A JScrollPane is designed to display a single JTable. The header of the JTable will be displayed at the header view of the scroll pane and the table will be displayed in the center of the scroll pane. You may then also see scrollbars in the scroll pane depending on the data in the table.
If you want to "merge" data from multiple files into the same table, then you need to update the TableModel with the data from each file instead of creating a new table each time.
You can dynamically add data to the model by using the addRow(…) method of the DefaultTableModel.
For displaying each JTable into JFrame,i added all JTable into a JPanel and added this JPanel into JScrollPane.After displaying each JTable the problem was that we can not display each JTable header.I added to another JPanel each JTable header and it's shows up.
if (e.getSource() == jbtreadbrowsefile) {
GridLayout grid = new GridLayout(0, 1, 30, 20);
jpaneltable=new JPanel(grid);
try {
for(int k=0;k<file_locations.length;k++) {
String currentLocation=file_locations[k];
inputList = new ArrayList();
File inputF = new File(currentLocation);
InputStream inputFS = new FileInputStream(inputF);
BufferedReader br = new BufferedReader(new InputStreamReader(inputFS));
inputList = br.lines().collect(Collectors.toList());
br.close();
int count = inputList.size();
if(count>0)
{
data = new String[count - 1][8];
for (int i = 0; i < count - 1; i++) {
String[] arrOfStr = inputList.get(i + 1).toString().split(",");
String test1= arrOfStr[0];
String test2= arrOfStr[1];
String test3= arrOfStr[2];
String test4= arrOfStr[3];
String test5= arrOfStr[4];
String test6= arrOfStr[5];
String test7= arrOfStr[6];
data[i][0] = "" + (i + 1);
data[i][1] = test1;
data[i][2] = test2;
data[i][3] = test3;
data[i][4] = test4;
data[i][5] = test5;
data[i][6] = test6;
data[i][7] = test7;
}
j = new JTable(data, columnNames);
TableColumnModel tcm = j.getColumnModel();
tcm.getColumn(0).setPreferredWidth(40);
tcm.getColumn(1).setPreferredWidth(220);
tcm.getColumn(2).setPreferredWidth(120);
tcm.getColumn(3).setPreferredWidth(80);
tcm.getColumn(4).setPreferredWidth(80);
tcm.getColumn(5).setPreferredWidth(80);
tcm.getColumn(6).setPreferredWidth(80);
tcm.getColumn(7).setPreferredWidth(80);
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
j.getColumnModel().getColumn(0).setCellRenderer(centerRenderer);
for (int i = 0; i < j.getRowCount(); i++) {
j.setRowHeight(i, 20);
}
j.getTableHeader().setFont(new Font("SansSerif", Font.BOLD, 15));
j.getTableHeader().setReorderingAllowed(false);
j.getTableHeader().setPreferredSize(new Dimension(0,HEADER_HEIGHT));
j.repaint();
jpaneltable.add(j.getTableHeader(),BorderLayout.NORTH);
jpaneltable.add(j, BorderLayout.CENTER);
}
else
{
JOptionPane.showMessageDialog(this,"No Data Found in the File");
}
}
JScrollPane sp = new JScrollPane(jpaneltable,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sp.setBounds(10, 200, 780, 440);
add(sp);
}

FormLayout displays everything in one cell

I am trying to create a grid using FormLayout but it seems it displays every new element above the others. I guess the problem is with CellContraints and FormLayout. Note that CityPanel extends Panel.
public class MapPanel extends JPanel {
public MapPanel() {
drawMap(5, 5);
}
private void drawMap(columns, rows) {
ColumnSpec[] columnSpec = new ColumnSpec[columns];
for(int i = 0; i < columns; i++)
columnSpec[i] = FormSpecs.DEFAULT_COLSPEC;
RowSpec[] rowSpec = new RowSpec[rows];
for(int i = 0; i < rows; i++)
rowSpec[i] = FormSpecs.DEFAULT_ROWSPEC;
FormLayout layout = new FormLayout(columnSpec, rowSpec);
this.setLayout(layout);
CellConstraints cc = new CellConstraints(columns, rows);
//draw the grid
for (City city : gameMap.getCities().values()) {
Dimension dimension = new Dimension(100, 100);
CityPanel cityPanel = new CityPanel(city, dimension);
//this code put the cityPanel in a cell. It's confirmed by the println()
this.add(cityPanel, cc.xy(mapGrid.getColumn(city), mapGrid.getRow(city), CellConstraints.CENTER, CellConstraints.CENTER));
System.out.println(city.getName() + " -> (" + mapGrid.getColumn(city) + "," + mapGrid.getRow(city) + ")" );
}
}
}

how can I "refresh" my table, so that I could display same table with different data?

How can I "refresh" my table, so that I could display same table with different data?
String columnNames[] = {"First Name", "Last Name", "Phone Number", "E-mail"};
JTable contactTable = new JTable(data, columnNames);
jScrollPane = new JScrollPane(contactTable,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
where is your data saved ?
i save it in a text file and use this way to refresh my data but you need a button to refresh every time
here is my code
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// Refresh Button
try {
for (int r = 0; r < 100; r++) { //initializing row
for (int c = 0; c < 4; c++) { //initializing column
jTable1.setValueAt(null, r, c);
}
}
BufferedReader rdfile = new BufferedReader(new FileReader("items.txt"));
String[] item = new String[100];
String[] temp;
int x = 0; //read item
while ((item[x] = rdfile.readLine()) != null) {
temp = item[x].split("\t");
jTable1.setValueAt((1000 + x + 1), x, 0);
for (int j = 1; j < 4; j++) {
jTable1.setValueAt(temp[j - 1], x, j);
}
x++;
}
rdfile.close();
} catch (IOException e) {
}
}

SWT Table don't see items from other columns

I added columns on code:
String[] titles = {"Nazwa", "Uzytkownik", "Haslo"};
for(int i=0; i<titles.length; i++){
TableColumn column = new TableColumn(table, SWT.NULL);
column.setText(titles[i]);
}
Next, I added items to said columns:
String[][] a = new String[passwords.length][3];
for(int i=0; i<passwords.length; i++){
a[i] = passwords[i].split(":");
}
for(int i=0; i<passwords.length; i++){
TableItem item = new TableItem(table, SWT.NULL);
//item.setText(Integer.toString(i));
for(int j=0; j<a[i].length; j++){
item.setText(j, a[i][j]);
}
}
Now, I want get selected items from the second column.
I added TableCursor and KeyListener:
tableCursor.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if(e.character == 'c') {
Point p = tableCursor.getLocation();
//for(int i=0; i<selection.length; i++){
TableItem item = table.getItem(p);
if(item != null){
MessageBox message = new MessageBox(shell, SWT.ICON_ERROR);
message.setMessage(item.toString());
message.open();
}
}
}
});
And now, for example, when I select item from the second column, it doesn't see anything from the second column, only item from the first column. What's the problem?
The problem is the way you try to find the selected item/column in the table.
Here is an example that does exactly what you want:
public static void main(String[] args)
{
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Table table = new Table(shell, SWT.NONE);
table.setHeaderVisible(true);
/* Create columns */
for (int i = 0; i < 3; i++)
{
TableColumn col = new TableColumn(table, SWT.NONE);
col.setText("Col " + i);
}
/* Create items */
for (int i = 0; i < 10; i++)
{
TableItem item = new TableItem(table, SWT.NONE);
item.setText(new String[] { "Row" + i + "Col1", "Row" + i + "Col2", "Row" + i + "Col3" });
}
/* Pack columns */
for (int i = 0; i < 3; i++)
{
table.getColumn(i).pack();
}
table.addListener(SWT.MouseUp, new Listener()
{
#Override
public void handleEvent(Event event)
{
Point pt = new Point(event.x, event.y);
TableItem item = table.getItem(pt);
if (item != null)
{
/* Iterate over all columns and check if event is contained */
for (int col = 0; col < table.getColumnCount(); col++)
{
Rectangle rect = item.getBounds(col);
if (rect.contains(pt))
{
System.out.println(item.getText(col));
}
}
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}

JTable & JTextField used for input. JTable is updateable. DocumentListener used for JTextField. Event doesn't fire. How to get event?

import java.awt.*;
import java.awt.Component;
import java.lang.*;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.event.*;
import javax.swing.text.Document;
import javax.swing.text.*;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.*;
import java.util.*;
public class Test1 extends JApplet
{
Object dummya [][] = new Object [9][9]; // Setup 2-Dimensional Arrays
int inputa [][] = new int [9][9];
int possiblea [][] = new int [81][9];
int solveda [][] = new int [9][9];
String ic = "B";
String nl = "\n";
String col_h [] = {"G1", "G2", "G3", "G4", "G5", "G6", "G7", "G8", "G9"};
Font f = new Font ("Courier", Font.BOLD, 10);
Font h = new Font ("Times Roman", Font.BOLD, 14);
JTextField uc = new JTextField (1);
JTextField st = new JTextField (75);
int gs = 55;
int wl = 1;
int ts = col_h.length;
DefaultTableModel dm = new DefaultTableModel(dummya, col_h) { // Setup the Table Model
public String getColumnName (int col) {return col_h[col];}
public int getColumnCount() {return 9;} // Setup a 9x9 Table with headers
public int getRowCount() {return 9;}
public void setValueAt (Object foundValue, int row, int col) {
// st.setText ("At setValueAt.");
// inputa[row][col] = (Integer) foundValue;
fireTableCellUpdated (row, col);
}
};
JTable table = new JTable (dm); // Create the Table
public void init () {
Container c = getContentPane (); // Get a Container for User View
Color lc = new Color (240, 128, 128); // Set Light Coral Color
c.setBackground (lc);
c.setFont (f);
table.getTableHeader().setResizingAllowed (false); // Setup all the Table rules
table.getTableHeader().setReorderingAllowed (false);
table.setSelectionMode (javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
for (int i = 0; i < ts; i++) { // Resize Columns & Rows to 40 pixels
TableColumn column = table.getColumnModel().getColumn(i);
column.setMinWidth (40);
column.setMaxWidth (40);
column.setPreferredWidth (40);
table.setRowHeight (i, 40);
}
table.getModel().addTableModelListener (
new TableModelListener() {
public void tableChanged(TableModelEvent e) {
tableDataChanged (e);
}
});
c.setLayout (new FlowLayout (FlowLayout.CENTER, 340, 0)); // Setup a Layout & add Components
c.add (new JLabel (" "));
c.add (new JLabel ("Challenge", SwingConstants.CENTER));
c.add (new JLabel (" "));
c.add (new JLabel ("By Author X", SwingConstants.CENTER));
c.add (new JLabel (" ")); // Add a pad line
c.setFont (h);
table.setGridColor (Color.red); // Setup Table View
c.add (table.getTableHeader()); // Add Column Headers
c.add (table); // Show the Table
c.add (new JLabel (" "));
uc.setBackground (lc);
c.add (new JLabel (" Enter Command (C,F,H,L,I,P,S): ", SwingConstants.CENTER));
c.add (uc); // Add a User Command Field
uc.setEditable (true); // Allow Input in Command Field
uc.requestFocusInWindow();
c.add (new JLabel (" "));
st.setBackground (lc);
c.add (st); // Add a Status area
st.setEditable (false);
uc.getDocument().addDocumentListener (new DocumentListener() { // Listen for JTextField command
public void changedUpdate(DocumentEvent e) {
editInput();
}
public void insertUpdate(DocumentEvent e) {
editInput();
}
public void removeUpdate(DocumentEvent e) {}
});
}
// The following section is driven by a user command.
public void run () { // To keep the Applet running, just loop
int loopcnt = 0;
while (wl != -1) {
loopcnt++;
if (loopcnt == 100) {
try { Thread.sleep (10000); } // Sleep for 10 seconds to allow solve
catch (InterruptedException e) {} // thread to run.
loopcnt = 0;
}
}
}
private void editInput () { // Scan user command
try { ic = uc.getText (0, 1); } // Pick up user command
catch (BadLocationException be) { return; }
st.setText (" User Input is: " + ic);
if (ic == "C" || ic == "c") clearComponents ();
else if (ic == "E" || ic == "e") {
st.setText (" User Exit.");
wl = -1;
}
else if (ic == "H" || ic == "h") newFrame();
// else if (ic == "F" || ic == "f") getHintAtFirst(); // Get a hint where only 2 values possible
// else if (ic == "L" || ic == "l ") getHintAtLast();
// else if (ic == "I" || ic == "i") StartThread(); // Look into wait and Notify
// else if (ic == "P" || ic == "p") printGrid();
// else if (ic == "S" || ic == "s") solveAndShow();
// else st.setText (" Invalid Command, try again.");
}
public void clearComponents () { // Clear Arrarys and Table View
for (int i = 0; i < ts; i++) {
for (int j = 0; j < ts; j++) {
dummya[i][j] = null;
inputa[i][j] = 0;
possiblea[i][j] = 0;
solveda[i][j] = 0;
table.setValueAt (null, i, j);
}
}
st.setText (" Table Cleared.");
}
private void newFrame () { // Setup the Possibles frame
JFrame possibles = new JFrame ("Grid Possibilities");
possibles.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
possibles.setBounds (550, 0, 440, 580);
JTextArea ta = new JTextArea ();
JScrollPane sp = new JScrollPane ();
possibles.add (ta);
possibles.add (sp);
possibles.pack ();
possibles.validate ();
possibles.setVisible (true);
}
public void tableDataChanged (TableModelEvent e) { // Process & Edit user input
int row = e.getFirstRow();
int col = e.getColumn();
// TableModel model = (TableModel) e.getSource();
// String cn = model.getColumnName (col);
for (int i = row; i < ts; i++) { // Scan the input for values
for (int j = col; i < ts; j++) {
dummya [row][col] = table.getValueAt (i, j);
int newValue = (Integer) dummya [row][col];
int rc = integerEditor (1, 9, newValue); // Go check the user input
if (rc == 0) {
st.setText ("Input Value is " + newValue);
inputa [row][col] = (Integer) dummya [row][col]; // Store the grid value
}
else st.setText ("Input Value is invalid at " + row+1 + "," + col+1 + ".");
}
}
}
private int integerEditor (int va, int vb, int value) { // Edit user input
if (value < va || value > vb) return -1;
return 0;
}
}
DefaultCellEditor dce = (DefaultCellEditor)table.getDefaultEditor(Object.class);
JTextField editor = (JTextField)dce.getComponent();
editor.addDocumentListener(...);

Categories

Resources