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) + ")" );
}
}
}
Related
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);
}
I am fairly new to programming and I cant seem to find the problem in the area where I make the program search for the specific key term tho it's saved in the array.
here is the code where I add the details of the customer:
private void addCustomerToSeat(String[] seatBooking, String[] customerName, String[] seatBookingAndCustomerName) {
Button[] seat = new Button[(SEATING_CAPACITY + 1)];
Button selectSeat = new Button(" Click to Book Seats ");
selectSeat.setLayoutX(320);
selectSeat.setLayoutY(512);
selectSeat.setOnAction(event -> {
window.setScene(scene2);
});
Label header = new Label("TRAIN BOOKING SYSTEM");
header.setLayoutX(250);
header.setLayoutY(30);
header.setStyle("-fx-font-size: 25px;");
Label clientName = new Label("Enter Customer Name: ");
clientName.setLayoutX(225);
clientName.setLayoutY(150);
clientName.setStyle("-fx-font-size: 16px;");
TextField cusName = new TextField();
cusName.setLayoutX(397);
cusName.setLayoutY(150);
Label destination = new Label("Choose destination: ");
destination.setLayoutX(225);
destination.setLayoutY(200);
destination.setStyle("-fx-font-size:16px;");
String [] destinations = {"Colombo to Badulla", "Badulla to Colombo"};
ComboBox Destination = new ComboBox(FXCollections.observableArrayList(destinations));
Destination.setLayoutX(397);
Destination.setLayoutY(200);
Label date = new Label("Select date:");
date.setLayoutY(275);
date.setLayoutX(225);
date.setStyle("-fx-font-size:16px;");
DatePicker datePicker = new DatePicker();
LocalDate now = LocalDate.now();
datePicker.setValue(now);
datePicker.setLayoutX(397);
datePicker.setLayoutY(275);
AnchorPane layout1 = new AnchorPane();
layout1.setStyle("-fx-background-color:#5a89a3; ");
layout1.getChildren().addAll(Destination,destination,selectSeat,clientName,cusName,header,date,datePicker);
scene1 = new Scene(layout1,800,600);
window.setTitle("Train Booking System");
window.setScene(scene1);
window.show();
Label header1 = new Label("TRAIN BOOKING SYSTEM");
header1.setLayoutX(250);
header1.setLayoutY(30);
header1.setStyle("-fx-font-size: 25px;");
Button submit = new Button("Submit");
submit.setLayoutX(640);
submit.setLayoutY(480);
Button exit = new Button("Exit");
exit.setLayoutX(710);
exit.setLayoutY(480);
exit.setOnAction(event -> {
window.close();
displayMenu(seatBooking,customerName,seatBookingAndCustomerName);
});
Label greenSeat = new Label("Unbooked Seat");
greenSeat.setLayoutY(160);
greenSeat.setLayoutX(590);
greenSeat.setStyle("-fx-font-size:14px;");
Button unbooked = new Button(" ");
unbooked.setLayoutY(160);
unbooked.setLayoutX(560);
unbooked.setStyle("-fx-background-color:green;");
Label redSeat = new Label("Booked Seat");
redSeat.setLayoutX(590);
redSeat.setLayoutY(200);
redSeat.setStyle("-fx-font-size:14px;");
Button booked = new Button(" ");
booked.setLayoutX(560);
booked.setLayoutY(200);
booked.setStyle("-fx-background-color:red;");
GridPane gridPane = new GridPane();
int columnIndex = 0;
int rowIndex = 0;
int rowIndexes = 0;
int[] reservedSeats = new int[1];
String seatNumber;
for (int i = 1; i < (SEATING_CAPACITY + 1); i++) {
if (i <= 9) {
seatNumber = "0" + (i);
} else {
seatNumber = "" + (i);
}
seat[i] = new Button(seatNumber);
gridPane.add(seat[i], columnIndex, rowIndex);
columnIndex++;
rowIndexes++;
if (rowIndexes == 4) {
columnIndex = 0;
rowIndexes = 0;
rowIndex++;
}
}
for (int f = 1; f < (SEATING_CAPACITY + 1); f++) {
if (seatBooking[f].equals("Empty")) {
seat[f].setStyle("-fx-background-color: green;");
}
if (seatBooking[f].equals("booked")) {
seat[f].setStyle("-fx-background-color: red");
}
}
List<Integer> bookedCurrent = new ArrayList<>();
for (int f = 1; f < (SEATING_CAPACITY + 1); f++) {
int finalF = f;
seat[f].setOnAction(event -> {
seat[finalF].setStyle("-fx-background-color: red");
seatBooking[finalF] = "booked";
bookedCurrent.add(finalF);
});
submit.setOnAction(event -> {
String personName = cusName.getText();
personName = personName.toLowerCase();
window.close();
for ( int loopSeatArray = 1; loopSeatArray< (SEATING_CAPACITY + 1); loopSeatArray++) {
if (loopSeatArray == reservedSeats[0]) {
seatBooking[loopSeatArray] = "Booked";
customerName[loopSeatArray] = personName;
}
seatBookingAndCustomerName[loopSeatArray] = seatBooking[loopSeatArray];
}
for (int total = 43; total < (SEATING_CAPACITY + 1); total++){
seatBookingAndCustomerName[total]= customerName[total-42]; }
displayMenu(seatBooking, customerName, seatBookingAndCustomerName);
});
}
gridPane.setLayoutX(160);
gridPane.setLayoutY(80);
gridPane.setHgap(20);
gridPane.setVgap(5);
AnchorPane layout2 = new AnchorPane();
layout2.setStyle("-fx-background-color:#5a89a3; ");
layout2.getChildren().addAll(gridPane,submit,exit,header1,greenSeat,unbooked,redSeat,booked);
scene2 = new Scene(layout2,800,600);
window.setTitle("Train Booking System");
window.show();
window.setOnCloseRequest(event -> {
window.close();
displayMenu(seatBooking,customerName,seatBookingAndCustomerName);
});
}
and here is the part of the code where I prompt the user for the name and find the location of given name:
private void findCustomerSeats(String[] seatBooking, String[] customerName, String[] seatBookingAndCustomerName) {
Scanner input = new Scanner(System.in);
System.out.println("Please enter customer name: ");
String name = input.nextLine();
boolean flag = false;
for (int i = 1; i < (SEATING_CAPACITY + 1); i++){
if (name.toLowerCase().equals(customerName[i])){
System.out.println("Seats booked are: " + seatBooking);
flag = true;
}
}
if (flag !=true){
System.out.println(name + " has not reserved a seat");
}
displayMenu(seatBooking,customerName,seatBookingAndCustomerName);
}
when the above code is run, and when I input the name, it plain out does not work.
One potential issue, your for loop is starting at index 1, I would begin by using something like this:
for (int idx = 0; idx < customerName.length; idx++) {
//This way you will not check an index of your array that does not exist
//which could cause a NullPointerException
//Additionally, this is useful if you want to grow your customerName array
}
Another useful tip, that I use all the time. Try printing out more information and see if you can spot the issue. This might seem trivial but I have found it extremely helpful. For example:
System.out.println("Inputted Name: " + name);
for (int idx = 0; idx < customerName.length; idx++) {
System.out.println("Does " + name.toLowerCase() + " = " + customerName[idx] + " ?");
}
I'm trying to create a hangman game using the Swing class and Graphics class for a APCS class I have.
I created a JButton that would take the guess typed in by the user and either add it to the "misses" or fill in all of the corresponding letters in the word. I have a separate txt file where I pick a random word from.
When I run the program, all of the components show up, but the button does not do anything. I have been working on this for a few days and don't know what I am doing wrong. I have only learnt how to use the Swing class recently, so it may be a stupid mistake for all I know. I have put all of the code down below.
public class Hangman extends JFrame {
DrawPanel panel = new DrawPanel();
Graphics g = panel.getGraphics();
JTextField guess;
JTextField outputWord;
JTextField missesString;
boolean play;
JButton button = new JButton();
String output = "";
String word;
int misses = 0;
public Hangman() {
int again = 0;
String[] dictionary = new String[1000];
In words = new In("words.txt");
JFrame app = new JFrame();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setVisible(true);
app.setSize(500, 500);
for (int i = 0; i < 1000; i++) {
dictionary[i] = words.readLine();
}
do {
int num = (int) (Math.random() * 1000);
word = dictionary[num].toLowerCase();
String answer = word;
word = "";
for (int i = answer.length(); i > 0; i--) {
word = word + "*";
}
int length = answer.length();
app.setLayout(new BorderLayout());
JLabel letter = new JLabel();
letter.setFont(new Font("Arial", Font.BOLD, 20));
letter.setText("Enter Your guess");
guess = new JTextField(10);
JLabel output = new JLabel();
output.setFont(new Font("Arial", Font.BOLD, 20));
output.setText("The Word is");
outputWord = new JTextField(30);
outputWord.setText(word);
outputWord.setEditable(false);
JLabel misses = new JLabel();
misses.setFont(new Font("Arial", Font.BOLD, 20));
misses.setText("Misses:");
missesString = new JTextField(52);
missesString.setEditable(false);
button = new JButton("Guess");
button.addActionListener(new ButtonListener());
JPanel panels = new JPanel();
panels.setLayout(new BorderLayout());
JPanel panel1 = new JPanel();
panel1.add(letter);
panel1.add(guess);
panel1.add(button);
JPanel panel2 = new JPanel();
panel2.add(output);
panel2.add(outputWord);
JPanel panel3 = new JPanel();
panel3.add(misses);
panel3.add(missesString);
app.add(panel1, BorderLayout.NORTH);
app.add(panel2, BorderLayout.EAST);
app.add(panel3, BorderLayout.SOUTH);
app.add(panels);
app.setVisible(true);
again = JOptionPane.showConfirmDialog(null, "Do you want to play again?");
} while (again == JOptionPane.YES_OPTION);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == guess) {
output = "";
}
for (int i = 0; i <= word.length() - 1; i++) {
if (guess.getText().equalsIgnoreCase(word.substring(i, i + 1))) {
output = output.substring(0, i) + guess + output.substring(i + 1, word.length() - 1);
outputWord.setText(output);
} else {
misses++;
missesString.setText(missesString.getText() + guess + " ");
}
}
}
}
}
The components show up perfectly on the screen, it is only the button that is giving me a hard time by not working as expected.
I am trying to combign tiff image and shapefile and want show it. For this, I am using GeoTiff and I am stuck that my tiff file is now being displayed. Shapefile is showing properly but tiff image, which is having only 1 band and grey scale index, is not being shown because of some reason. I am getting one warning message as below.
2016-08-04T12:43:06.456+0530 WARNING Possible use of "Transverse_Mercator" projection outside its valid area.
Latitude 180°00.0'S is out of range (±90°).
How can I remove this message?
My code is as below
private void displayLayers() throws Exception {
AbstractGridFormat format = GridFormatFinder.findFormat(this.getBlueMarble());
this.setGridCoverageReader(format.getReader(this.getBlueMarble()));
Style rgbStyle = this.createRGBStyle();
// connect to the shapefile
FileDataStore dataStore = FileDataStoreFinder.getDataStore(this.getBorderShape());
SimpleFeatureSource shapefileSource = dataStore.getFeatureSource();
Style shpStyle = SLD.createPolygonStyle(Color.BLUE, null, 0.0f);
MapContent map = new MapContent();
map.getViewport().setCoordinateReferenceSystem(
DefaultGeographicCRS.WGS84);
map.setTitle("Illegal Mining");
Layer rasterLayer = new GridReaderLayer(this.getGridCoverageReader(), rgbStyle);
map.addLayer(rasterLayer);
Layer shpLayer = new FeatureLayer(shapefileSource, shpStyle);
map.addLayer(shpLayer);
System.out.println("Trying to show on map...");
JMapPane mapPane = new JMapPane();
mapPane.setMapContent(map);
mapPane.setDisplayArea(shapefileSource.getBounds());
//mapPane.setDisplayArea(this.getGridCoverageReader().getOriginalEnvelope());
this.add(mapPane, BorderLayout.CENTER);
}
private Style createRGBStyle() {
GridCoverage2DReader reader = this.getGridCoverageReader();
StyleFactory sf = this.getStyleFactory();
GridCoverage2D cov = null;
try {
cov = reader.read(null);
} catch (IOException giveUp) {
throw new RuntimeException(giveUp);
}
// We need at least three bands to create an RGB style
int numBands = cov.getNumSampleDimensions();
System.out.println("numBands:"+numBands);
if (numBands < 3) {
System.out.println("Bands are less than 3");
//return null;
}
// Get the names of the bands
String[] sampleDimensionNames = new String[numBands];
for (int i = 0; i < numBands; i++) {
GridSampleDimension dim = cov.getSampleDimension(i);
sampleDimensionNames[i] = dim.getDescription().toString();
}
final int RED = 0, GREEN = 1, BLUE = 2;
int[] channelNum = { -1, -1, -1 };
Boolean greyflag=false;
// We examine the band names looking for "red...", "green...",
// "blue...".
// Note that the channel numbers we record are indexed from 1, not 0.
for (int i = 0; i < numBands; i++) {
String name = sampleDimensionNames[i].toLowerCase();
System.out.println("name :"+name);
if (name != null) {
if (name.matches("red.*")) {
channelNum[RED] = i + 1;
} else if (name.matches("green.*")) {
channelNum[GREEN] = i + 1;
} else if (name.matches("blue.*")) {
channelNum[BLUE] = i + 1;
}else if(name.matches("gray.*")){
System.out.println("What to do here");
channelNum[RED] = 1;
channelNum[GREEN] = 2;
channelNum[BLUE] = 3;
greyflag=true;
}
}
}
// If we didn't find named bands "red...", "green...", "blue..."
// we fall back to using the first three bands in order
if(greyflag==false){
if (channelNum[RED] < 0 || channelNum[GREEN] < 0
|| channelNum[BLUE] < 0) {
channelNum[RED] = 1;
channelNum[GREEN] = 2;
channelNum[BLUE] = 3;
}
}
// Now we create a RasterSymbolizer using the selected channels
SelectedChannelType[] sct = new SelectedChannelType[cov
.getNumSampleDimensions()];
ContrastEnhancement ce = sf.contrastEnhancement(this.ff.literal(1.0),
ContrastMethod.NORMALIZE);
for (int i = 0; i < numBands; i++) {
sct[i] = sf.createSelectedChannelType(
String.valueOf(channelNum[i]), ce);
System.out.println(String.valueOf(channelNum[i]));
}
RasterSymbolizer sym = sf.getDefaultRasterSymbolizer();
ChannelSelection sel =sf.channelSelection(sct[RED]);
if(numBands>1){
sel = sf.channelSelection(sct[RED], sct[GREEN],
sct[BLUE]);
}
sym.setChannelSelection(sel);
return SLD.wrapSymbolizers(sym);
}
I just pass two files as below code
public MapImagePanel() {
this.setLayout(new BorderLayout(0, 0));
this.setBackground(Color.BLUE);
this.setPreferredSize(new Dimension(720, 360));
this.setBlueMarble(new File("E:/tifffilename.TIFF"));
this.setBorderShape(new File("E:/shapefilename.shp"));
try {
this.displayLayers();
} catch (Exception e) {
e.printStackTrace();
}
}
This is how i use this class in main class
//see output in main method
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MapImagePanel panel = new MapImagePanel();
panel.setPreferredSize(new Dimension(1024,768));
panel.setVisible(true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
frame.show();
TLDR; add the following line to your program start up:
System.setProperty("org.geotools.referencing.forceXY", "true");
From GeoTools FAQ as computer programmers they knew that coordinates would be expressed as longitude,latitude pairs so they could use existing graphics code easily by treating them as a simple (x,y) pair. but for sequence like (x,y) or (y,x) they confused that is why this error is coming.
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