JTable Properly aligning inside JScrollPane - java

I have a JTable inside a JScrollView But It doesn't seem to be aligned well more over the scroll bar is tiny i am guessing that this is because of the alignment.Moreover it is here is a snippet from the real code :
JFrame frame = new JFrame();
frame.setResizable(false);
frame.setBounds(100, 100, 771, 453);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
panel.setBounds(10, 32, 747, 370);
frame.getContentPane().add(panel);
panel.setLayout(null);
JPanel VPanel = new JPanel();
VPanel.setBounds(297, 43, 440, 224);
panel.add(VPanel);
JTable TableV = new JTable();
TableV.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
TableV.getTableHeader().setReorderingAllowed(false);
DefaultTableModel Model = new DefaultTableModel(0, 0);
String header[] = new String[] { "Country", "ID", "WAN IP", "User", "OS", "Java version" };
VPanel.add(new JScrollPane(TableV, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
// just adding some data to fill the table
Model.setColumnIdentifiers(header);
//set model into the table object
TableV.setModel(Model);
//just adding some diff data to check if it scrolls down
for (int count = 1; count <= 50; count++)
{
Model.addRow(new Object[] { "data1", "data2", "data3", "data4", "data5", "data6" });
}
for (int count = 1; count <= 70; count++)
{
Model.addRow(new Object[] { "data100", "data200", "data300", "data400", "data500", "data600" });
}
frame.setVisible(true);

Understand that VPanel (which should be renamed vPanel to comply with Java naming rules) uses FlowLayout, and so the scrollpane may not fit well within it. Give it a BorderLayout and add the JScrollPane BorderLayout.CENTER if you want the scroll pane to fill it.
e.g.,
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("serial")
public class TableFoo extends JPanel {
private static final String[] HEADER = new String[] { "Country", "ID", "WAN IP", "User", "OS", "Java version" };
private static final int PREF_W = 500;
private static final int PREF_H = 400;
private DefaultTableModel model = new DefaultTableModel(HEADER, 0);
private JTable table = new JTable(model);
public TableFoo() {
for (int count = 0; count < 50; count++) {
model.addRow(new Object[] { "data1", "data2", "data3", "data4", "data5", "data6" });
}
for (int count = 0; count < 70; count++) {
model.addRow(new Object[] { "data100", "data200", "data300", "data400", "data500", "data600" });
}
JScrollPane scrollPane = new JScrollPane(table);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("TableFoo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TableFoo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Related

How to copy one row from JTable into another JTable

I work on my projekt where i need to copy one row from JTable into another JTable, the second JTable should be only one-row table. I created mouselistener to first JTable where on doubleclick it should copy row and insert it into another JTable but it doesn't work correctly, any ideas how to solve it? i Get the data from database in first table. with code:
public void cputable() {
try {
conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test","postgres","postgres");
stat = conn.createStatement();
result = stat.executeQuery("SELECT name,bus_speed,socket,cores,chipset,price*1.3 FROM CPU");
cputable.setModel(DbUtils.resultSetToTableModel(result));
result.close();
stat.close();
}
catch (Exception e){
e.printStackTrace();
}
}
and here is the code which i try to copy row:
cputable.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
JTable cputable =(JTable) me.getSource();
int row = cputable.getSelectedRow();
int col = cputable.getColumnCount();
if (me.getClickCount() == 2) {
cputablebottom.repaint();
for(int i = 0; i < col; i++) {
DefaultTableModel model = (DefaultTableModel) cputable.getModel();
List<String>list = new ArrayList<String>();
list.add( cputable.getValueAt(row, i).toString());
model.addRow(list.toArray());
cputablebottom.setModel(model);
}
Result before and after:
EDIT:
I remake a bit in the code and now it copy the whole list instead of only one row.
cputable.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
JTable cputable =(JTable) me.getSource();
int row = cputable.getSelectedRow();
int col = cputable.getColumnCount();
if (me.getClickCount() == 2) {
cputablebottom.repaint();
DefaultTableModel model1 = (DefaultTableModel) cputable.getModel();
List<String>list = new ArrayList<String>();
model1.addRow(list.toArray());
for(int i = 0; i < col; i++) {
list.add( cputable.getValueAt(row, i).toString());
cputablebottom.setModel(model1);
System.out.println(model1);
System.out.println(list);
}
cputablebottom.setModel(model1);
I've not tried this, but...
DefaultTableModel model1 = (DefaultTableModel) cputable.getModel();
Vector data = model1.getDataVector();
Object rowObj = data.get(row);
Vector newData = new Vector(1);
newData.add(rowObj);
DefaultTableModel model2 = (DefaultTableModel) cputablebottom.getModel();
model2.setRowCount(0);
model2.addRow(newData);
This should preserve the column information of the second table.
Alternatively, you could create a new DefaultTableModel, but you'd have to reconfigure the column information each time
What I suggest you do is have a read of the JavaDocs for DefaultTableModel
Tested example
I don't use DefaultTableModel often, preferring to put an actual object in each row, which I can then define how it is displayed, which would make it generally simpler, but, if a DefaultTableModel is all you have...
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Test");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTable top;
private JTable bottom;
public TestPane() {
setLayout(new GridLayout(2, 0));
String[][] rowData = new String[10][10];
for (int row = 0; row < 10; row++) {
String[] data = new String[10];
for (int col = 0; col < 10; col++) {
data[col] = row + "x" + col;
}
rowData[row] = data;
}
String[] names = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
DefaultTableModel model = new DefaultTableModel(rowData, names);
top = new JTable(model);
add(new JScrollPane(top));
DefaultTableModel emptyModel = new DefaultTableModel(new String[10][10], names);
bottom = new JTable(emptyModel);
add(new JScrollPane(bottom));
top.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
int row = top.rowAtPoint(e.getPoint());
if (row > -1) {
DefaultTableModel topModel = ((DefaultTableModel)top.getModel());
DefaultTableModel bottomModel = ((DefaultTableModel)bottom.getModel());
bottomModel.setRowCount(1);
for (int col = 0; col < topModel.getColumnCount(); col++) {
bottomModel.setValueAt(topModel.getValueAt(row, col), 0, col);
}
}
}
}
});
}
}
}
1.Code of 1st class where we are making our table-->
Sell.java
public class Sell extends JFrame {
public static void main(String args[]) {
new Sell();
}
JTextField tf1, tf2, tf3;
JButton b1, b2, b3;
JTable t1;
String s1;
public Sell() {
setBounds(450, 200, 600, 300);
setTitle("Sell");
Container con = getContentPane();
con.setBackground(Color.WHITE);
setLayout(null); // FlowLayout,GridLayout By default it is FlowLayout.
setVisible(true);
setResizable(false); // It allows to resize application size.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tf1 = new JTextField();
tf2 = new JTextField();
tf3 = new JTextField();
b1 = new JButton("Select");
b2 = new JButton("Add");
b3 = new JButton("Invoice");
t1 = new JTable(0, 2);
DefaultTableModel model = (DefaultTableModel) t1.getModel();
model.addRow(new Object[] { "Product", "Price" });
add(tf1);
add(tf2);
add(tf3);
add(b1);
add(b2);
add(b3);
add(t1);
tf1.setBounds(50, 50, 50, 20);
tf2.setBounds(25, 100, 100, 20);
tf3.setBounds(150, 100, 100, 20);
b1.setBounds(150, 45, 75, 30);
b2.setBounds(100, 195, 75, 30);
b3.setBounds(200, 195, 75, 30);
t1.setBounds(350, 50, 225, 200);
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
s1 = tf1.getText();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/vanisb",
"root", "spirit");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from product where ID='" + s1 + "';");
while (rs.next()) {
tf2.setText(rs.getString("product_name"));
tf3.setText(rs.getString("price"));
}
conn.close();
} catch (Exception ex) {
JOptionPane.showMessageDialog(b1, ex);
}
}
});
b2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
model.addRow(new Object[] { tf2.getText(), tf3.getText() });
}
});
b3.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new Invoice(model);
}
});
}
}
2.Code of 2nd class where we have to fetch the last table data-->
Invoice.java
public class Invoice extends JFrame {
public static void main(String[] args) {
}
JLabel l1, l2;
JTextField tf1, tf2;
JTable t2;
JButton b1;
public Invoice(DefaultTableModel model) {
setBounds(450, 200, 600, 300);
setTitle("Invoice");
Container con = getContentPane();
con.setBackground(Color.WHITE);
setLayout(null);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
l1 = new JLabel("Name : ");
l2 = new JLabel("Phone No. : ");
tf1 = new JTextField();
tf2 = new JTextField();
b1 = new JButton("Add Customer");
t2 = new JTable(model);
add(l1);
add(l2);
add(tf1);
add(tf2);
add(b1);
add(t2);
l1.setBounds(50, 50, 100, 20);
l2.setBounds(50, 100, 100, 20);
tf1.setBounds(150, 50, 100, 20);
tf2.setBounds(150, 100, 100, 20);
b1.setBounds(100, 175, 150, 30);
t2.setBounds(300, 50, 275, 200);
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
}
});
}
}

JScrollPane inside JPanel inside a JTabbedPane is not scrolling

I have this JPanel called CatalogPane, which is of size 800 by 600, which is inside a JTabbedPane inside a JFrame called BookFrame. So inside the CatalogPane, I created a JPanel called bookDisplay which displays a list of books and their details. I want it to be of size 780 by 900, leaving 20px for the scrollbar and taller than the frame so that it can scroll. Then I created a panel of size 800 by 400 because I need to leave some extra space at the bottom for other fields. I tried creating a JScrollPane for bookDisplay and then put it inside the other panel, but somehow the scrollbar appears but can't be used to scroll. I've experimented changing the sizes and scrollpane but I still can't get it to work.
What it looks like: http://prntscr.com/12j0d9
The scrollbar is there but can't work. I'm trying to get the scrollbar to work before I format the layout properly.
CatalogPane:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
public class CatalogPane extends JPanel{
//private Order currOrder = new Order();
//ArrayList<Book> bookCatalog = new ArrayList();
GridBagConstraints gbc = new GridBagConstraints();
GridBagLayout gbl = new GridBagLayout();
JPanel bookDisplay = new JPanel();
public CatalogPane()
{
//loadBookCatalog();
this.setPreferredSize(new Dimension(800, 600));
bookDisplay.setPreferredSize(new Dimension(780, 900));
bookDisplay.setLayout(new GridLayout(6, 5));
//bookDisplay.setLayout(gbl);
//gbc.fill = GridBagConstraints.NONE;
//gbc.weightx = 1;
//gbc.weighty = 1;
JLabel bookL = new JLabel("Books");
JLabel hardL = new JLabel("Hardcopy");
JLabel hardQuantL = new JLabel("Quantity");
JLabel eL = new JLabel("EBook");
JLabel eQuantL = new JLabel("Quantity");
bookDisplay.add(bookL);
bookDisplay.add(hardL);
bookDisplay.add(hardQuantL);
bookDisplay.add(eL);
bookDisplay.add(eQuantL);
/*
addComponent(bookL, 0, 0, 1, 1);
addComponent(hardL, 0, 1, 1, 1);
addComponent(hardQuantL, 0, 2, 1, 1);
addComponent(eL, 0, 3, 1, 1);
addComponent(eQuantL, 0, 4, 1, 1);
*/
Iterator<Book> bci = bookCatalog.iterator();
int row = 1;
/*
while(bci.hasNext())
{
Book temp = bci.next();
ImageIcon book1 = new ImageIcon(temp.getImage());
JLabel image = new JLabel(temp.getTitle(), book1, JLabel.CENTER);
image.setVerticalTextPosition(JLabel.TOP);
image.setHorizontalTextPosition(JLabel.CENTER);
String[] quant = {"1", "2", "3", "4", "5"};
JLabel hardP = new JLabel("$" + temp.getHardPrice());
JLabel eP = new JLabel("$" + temp.getEPrice());
JComboBox jbc1 = new JComboBox(quant);
JComboBox jbc2 = new JComboBox(quant);
jbc1.setSelectedIndex(0);
jbc2.setSelectedIndex(0);
/*
addComponent(b1temp, row, 0, 1, 1);
addComponent(hardP, row, 1, 1, 1);
addComponent(jbc1, row, 2, 1, 1);
addComponent(eP, row, 3, 1, 1);
addComponent(jbc2, row, 4, 1, 1);
row++;
bookDisplay.add(image);
bookDisplay.add(new JLabel("$" + temp.getHardPrice()));
bookDisplay.add(jbc1);
bookDisplay.add(new JLabel("$" + temp.getEPrice()));
bookDisplay.add(jbc2);
*/
for(int i=0;i<5;i++)
{
String[] quant = {"1", "2", "3", "4", "5"};
JComboBox jbc1 = new JComboBox(quant);
JComboBox jbc2 = new JComboBox(quant);
jbc1.setSelectedIndex(0);
jbc2.setSelectedIndex(0);
JLabel image = new JLabel("image");
bookDisplay.add(image);
bookDisplay.add(new JLabel("$" + 20));
bookDisplay.add(jbc1);
bookDisplay.add(new JLabel("$" + 15));
bookDisplay.add(jbc2);
}
JScrollPane vertical = new JScrollPane(bookDisplay);
//JPanel testP = new JPanel();
//testP.setPreferredSize(new Dimension(800, 400));
//JScrollPane vertical = new JScrollPane(testP);
//testP.add(bookDisplay);
vertical.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel testP = new JPanel();
testP.setPreferredSize(new Dimension(800, 400));
testP.add(vertical);
add(testP);
}
public void addComponent(Component c, int row, int col, int hei, int wid)
{
gbc.gridx = col;
gbc.gridy = row;
gbc.gridwidth = wid;
gbc.gridheight = hei;
gbl.setConstraints(c, gbc);
bookDisplay.add(c);
}
public Order getCurrOrder()
{
return currOrder;
}
private void loadBookCatalog()
{
try
{
String[] str = new String[8];
Scanner sc = new Scanner(new File("bookcat.txt"));
double temp1, temp2;
while(sc.hasNextLine())
{
str = sc.nextLine().split(";");
temp1 = Double.parseDouble(str[3]);
temp2 = Double.parseDouble(str[4]);
Book temp = new Book(temp1, temp2, str[0], str[1], str[2], str[5]);
bookCatalog.add(temp);
}
}
catch(IOException e)
{
System.out.println("File not found!");
}
}
}
BookFrame:
public class BookFrame extends JFrame{
JButton closeButton;
CatalogPane cp;
//IntroPane ip;
public BookFrame(String name)
{
super(name);
this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(new IntroPane()),
"Thank you for visiting Groovy Book Company.", "Message",
JOptionPane.INFORMATION_MESSAGE, new ImageIcon("coffee.jpg"));
System.exit(0);
}
});
//ip = new IntroPane();
cp = new CatalogPane();
JTabbedPane jtp = new JTabbedPane();
jtp.setPreferredSize(new Dimension(800, 600));
//jtp.addTab("Intro", ip);
jtp.addTab("Catalog", cp);
add(jtp);
pack();
setVisible(true);
}
}
I'd look at JTable, which handles scrolling and rendering as shown here and below. This example shows how to render images and currency. Start by adding a third column for quantity of type Integer. This related example illustrates using a JComboBox editor.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.text.NumberFormat;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
/**
* #see https://stackoverflow.com/a/16264880/230513
*/
public class Test {
public static final Icon ICON = UIManager.getIcon("html.pendingImage");
private JPanel createPanel() {
JPanel panel = new JPanel();
DefaultTableModel model = new DefaultTableModel() {
#Override
public Class<?> getColumnClass(int col) {
if (col == 0) {
return Icon.class;
} else {
return Double.class;
}
}
};
model.setColumnIdentifiers(new Object[]{"Book", "Cost"});
for (int i = 0; i < 42; i++) {
model.addRow(new Object[]{ICON, Double.valueOf(i)});
}
JTable table = new JTable(model);
table.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() {
#Override
protected void setValue(Object value) {
NumberFormat format = NumberFormat.getCurrencyInstance();
setText((value == null) ? "" : format.format(value));
}
});
table.setRowHeight(ICON.getIconHeight());
panel.add(new JScrollPane(table) {
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
});
return panel;
}
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane jtp = new JTabbedPane();
jtp.addTab("Test1", createPanel());
jtp.addTab("Test2", createPanel());
f.add(jtp);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
}

JDialog vs JOptionPane vs JPanel correct screen resize

I'm having endless problems when I need to show the user some very complex interface with save or cancel buttons and need this interface to correctly deal with different monitor resolutions.
Suppose for instance this interface needs to fit 17 JTextFields and a resizable JTextArea in a 1280 x 768 monitor (my 13'' laptop has vertical size of 760 pixel).
here is an SSCCE:
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame
{
private static Container layoutComponents(String title, float alignment)
{
JPanel container = new JPanel();
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
for (int i = 0, n = 7; i < n; i++)
{
JTextField jtextField= new JTextField("jtextfield "+i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add( new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20),
new java.awt.Dimension(32767, 20)));
}
JTextArea jTextArea = new JTextArea(15, 30);
container.add(jTextArea);
for (int i = 6, n = 13; i < n; i++)
{
JTextField jtextField= new JTextField("jtextfield "+i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add( new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20),
new java.awt.Dimension(32767, 20)));
}
return container;
}
public static void main(String args[])
{
Container panel1 = layoutComponents("Left", Component.LEFT_ALIGNMENT);
JOptionPane.showConfirmDialog(
null, panel1, "addRecord", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
}
}
Now I would like the above example to behave so that:
The size of the window resizes not cropping any of the content
The size of the window somehow deals differently based on the resolution of the monitor.
I dont' have to statically specify maximumSize, MinimumSize and preferredSize (with the NetBeans GUI editor for instance) so that each time I have to make numerous tests just to find out the correct size
the JtextArea resizes itself vertically depending on the vertical resolution up to a maximum.
You can add an option pane to a dialog, as shown here and here.
As an aside, call setSize() after pack().
Addendum: Here's a variation of your sscce that places the option pane in a scroll pane having an initial size based on screen geometry, as shown here.
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame {
private static Container layoutComponents(String title, float alignment) {
JPanel container = new JPanel();
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
for (int i = 0, n = 7; i < n; i++) {
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
JTextArea jTextArea = new JTextArea(15, 30);
container.add(jTextArea);
for (int i = 6, n = 13; i < n; i++) {
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
return container;
}
private static Box.Filler createFiller() {
return new Box.Filler(new Dimension(0, 20), new Dimension(0, 20),
new Dimension(Short.MAX_VALUE, 20));
}
public static void main(String args[]) {
Container panel = layoutComponents("Left", Component.LEFT_ALIGNMENT);
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
JScrollPane jsp = new JScrollPane(panel){
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 2 * screenSize.height / 3);
}
};
JOptionPane optPane = new JOptionPane();
optPane.setMessage(jsp);
optPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
optPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
JFrame f = new OptionPanePanel();
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.add(optPane);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
}
how can I show something like the above so that:
I don't know what that means. Post your SSCCE that shows us exactly the problem you are having.
This works fine for me:
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame
{
public OptionPanePanel()
{
JPanel panel = new JPanel( new BorderLayout() );
JPanel north = new JPanel();
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
JTextArea textArea = new JTextArea(5, 20);
panel.add(north, BorderLayout.NORTH);
panel.add(new JScrollPane(textArea));
int result = JOptionPane.showConfirmDialog(
this, panel, "addRecord", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
}
public static void main(String[] args)
{
JFrame frame = new OptionPanePanel();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
}
}
Thank you for you answers, so far I came with this solution: get the monitor height and if smaller than 1024 then show a small dialog within a JscrollPane (thanks to trashgod for pointing it), otherwise show a normal dialog with standard height (I have to calculate by trial unfortunately)
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame
{
private static Container layoutComponents(String title, float alignment)
{
JPanel container = new JPanel();
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
for (int i = 0, n = 7; i < n; i++)
{
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
JTextArea jTextArea = new JTextArea(15, 30);
container.add(jTextArea);
for (int i = 6, n = 13; i < n; i++)
{
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
return container;
}
private static Box.Filler createFiller()
{
return new Box.Filler(new Dimension(0, 20), new Dimension(0, 20),
new Dimension(Short.MAX_VALUE, 20));
}
public static void main(String args[])
{
Container panel = layoutComponents("Left", Component.LEFT_ALIGNMENT);
/*Let's check the monitor height in multi monitor setup */
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int monitorHeight = gd.getDisplayMode().getHeight();
int result;
if (monitorHeight <= 1024)
{
final Dimension preferredDimension = new Dimension(500, monitorHeight - 110);
panel.setPreferredSize(preferredDimension);
JScrollPane jsp = new JScrollPane(panel)
{
#Override
public Dimension getPreferredSize()
{
return new Dimension(500, 700);
}
};
result = JOptionPane.showOptionDialog(null, jsp,
"",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
new String[]
{
("save"), ("cancel")
}, // this is the array
"default");
}
else
{
final Dimension preferredDimension = new Dimension(500, 700);
panel.setPreferredSize(preferredDimension);
result = JOptionPane.showOptionDialog(null, panel,
"",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
new String[]
{
("save"), ("cancel")
}, // this is the array
"default");
}
if (result == JOptionPane.OK_OPTION)
{
//do something
}
}
}

Unable to get JScrollPane working on JFrame

Please look into the small code below. The scroll pane appears, but the sliders do not.
Even if I resize the frame the sliders do not. Please help.
import javax.swing.*;
public class sample {
static JFrame frame;
public static void main(String[] args) {
String Msg = "Sample Message To Test Scrolling";
frame = new JFrame("Sample Program");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
JPanel panel = new JPanel();
panel.setLayout(null);
for (int ypos = 0, i = 0; i < 40; i++) {
JLabel label = new JLabel("" + i + " " + Msg);
label.setFont(new Font("Courier", Font.BOLD, 12));
panel.add(label);
label.setBounds(10, ypos + 5,
label.getPreferredSize().width,
label.getPreferredSize().height);
ypos += label.getPreferredSize().height;
}
JScrollPane scroll = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
frame.setLayout(new BorderLayput());
frame.add(scroll);
frame.setVisible(true);
}
}
The sliders will only appear if and when the component contained by the JScrollPane's viewport is larger than the viewport. Based on your posted code, I don't see why your component would be larger than the viewport as the panel's size will be based on its preferredSize, something that will never change since for one, you're adding components to it with it using a null layout.
As an aside you should almost never use null layout.
For example:
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
public class Sample2 {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final int MAX_ROWS = 400;
private static final String TEXT_BODY = "Sample Message To Test Scrolling";;
private static void createAndShowGui() {
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
for (int i = 0; i < MAX_ROWS; i++) {
String text = String.format("%03d %s", i, TEXT_BODY);
JLabel label = new JLabel(text);
panel.add(label);
}
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setPreferredSize(new Dimension(PREF_W, PREF_H));
JFrame frame = new JFrame("Sample2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(scrollPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Jtable doesn't refresh/update data

I have a problem with JTable/JScrollPane. My data table is not refreshing/updating. I am using DefultTableModel and according to the code everything is fine and I don't have any errors. Also I have a table with paging and that's why I am using action listeners and buttons "prev" and "next". I am passing from other function to function that is coded in class where is JTable. Problem is that I fill arrays which contains data for table but table won't update/refresh it. Here is my code. Thanks advance.
BIG EDIT Old code was removed. I added new codes that will help you guys/girls to understand problem that I have. Hope that this will help. Regards.
First here is class that show gui:
import javax.swing.*;
public class Glavni {
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui Scanner = new gui();
Scanner.setVisible(true);
}
});
}
}
Second here is class that pass String to gui class that contains jtable
public class passDatatoTable {
public void passData(){
String str1,str2,str3,str4;
gui SendStringsToGUI = new gui();
for (int i =0;i<=10;i++){
str1="Column 1 of row: "+i;
str2="Column 2 of row: "+i;
str3="Column 3 of row: "+i;
str4="Column 4 of row: "+i;
SendStringsToGUI.WriteMonitorData(str1, str2, str3, str4);
}
}
}
Next here is declaration of gui (contructor):
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class gui extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
String[][] data = new String[100][4];
String[] columnNames = new String[]{
"IP", "PC_NAME", "ttl", "db"
};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
int i=0;
public void WriteMonitorData (String IP, String PC_NAME, String ttl, String gw)
{
System.out.println(IP);//just for testing (check if data was passed)
model.setValueAt(IP, i, 0);
model.setValueAt(PC_NAME, i, 1);
model.setValueAt(ttl, i, 2);
model.setValueAt(gw, i, 3);
i++;
model.fireTableDataChanged();
table.repaint();
scrollPane.repaint();
}
gui(){
JButton addData= new JButton("Add Data");
JButton next = new JButton("next");
JButton prev = new JButton("prev");
addData.addActionListener(this);
next.addActionListener(this);
prev.addActionListener(this);
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.add(addData);
buttonPanel.add(prev);
buttonPanel.add(next);
panel.add(buttonPanel, BorderLayout.SOUTH);
panel.add(table.getTableHeader(), BorderLayout.PAGE_START);
panel.add(scrollPane, BorderLayout.CENTER);
getContentPane().add(panel);
}
Here is actionListeners:
public void actionPerformed(ActionEvent e) {
if ("Add Data".equals(e.getActionCommand())){
passDatatoTable passSomeData = new passDatatoTable();
passSomeData.passData();
}
if ("next".equals(e.getActionCommand())) {
Rectangle rect = scrollPane.getVisibleRect();
JScrollBar bar = scrollPane.getVerticalScrollBar();
int blockIncr = scrollPane.getViewport().getViewRect().height;
bar.setValue(bar.getValue() + blockIncr);
scrollPane.scrollRectToVisible(rect);
}
if ("prev".equals(e.getActionCommand())) {
Rectangle rect = scrollPane.getVisibleRect();
JScrollBar bar = scrollPane.getVerticalScrollBar();
int blockIncr = scrollPane.getViewport().getViewRect().height;
bar.setValue(bar.getValue() - blockIncr);
scrollPane.scrollRectToVisible(rect);
}
}
Your first snippet shows this:
JTable table = new JTable(model);
but your gui() constructor shows:
JTable table = new JTable(data, columnNames);
You initiate the table twice. Once using the TableModel (JTable(TableModel tm)) the next using JTable(int rows,int cols) this is not good, initiate the JTable once in the constructor:
gui() {
DefaultTableModel model = new DefaultTableModel(data,columnNames);
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
JButton next = new JButton("next");
JButton prev = new JButton("prev");
next.addActionListener(this);
prev.addActionListener(this);
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.add(prev);
buttonPanel.add(next);
panel.add(buttonPanel, BorderLayout.SOUTH);
panel.add(table.getTableHeader(), BorderLayout.PAGE_START);
panel.add(scrollPane, BorderLayout.CENTER);
getContentPane().add(panel);
}
UPDATE:
Here is an example that has a thread which will start 2.5 secinds after the UI is visible and change a value of the JTable:
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class Test extends JFrame {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test().createAndShowUI();
}
});
}
private void createAndShowUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents(frame);
frame.pack();
frame.setVisible(true);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2500);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
model.setValueAt("hello", 0, 0);
}
});
}
}).start();
}
static DefaultTableModel model;
private void initComponents(JFrame frame) {
String data[][] = {
{"1", "2", "3"},
{"4", "5", "6"},
{"7", "8", "9"},
{"10", "11", "12"}
};
String col[] = {"Col 1", "Col 2", "Col 3"};
model = new DefaultTableModel(data, col);
JTable table = new JTable(model);
frame.getContentPane().add(new JScrollPane(table));
}
}
From what I understand from the comments and the question, you have first created a DefaultTableModel by passing the data as arrays in the constructor
String[][] data = new String[100][4];
String[] columnNames = new String[]{
"IP", "PC_NAME", "ttl", "db"};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
and you try to modify the table afterwards by adjusting those arrays. That will never ever have any effect, as the DefaultTableModel does not use those arrays. This can be seen in the source code of that class
public DefaultTableModel(Object[][] data, Object[] columnNames) {
setDataVector(data, columnNames);
}
which in the end comes down to
protected static Vector convertToVector(Object[][] anArray) {
if (anArray == null) {
return null;
}
Vector<Vector> v = new Vector<Vector>(anArray.length);
for (Object[] o : anArray) {
v.addElement(convertToVector(o));
}
return v;
}
So all the elements of the array are copied into an internal Vector and the array is no longer used.
Solution: do not update the arrays but update the DefaultTableModel. That class provides all the API you need to add/remove data to/from it.

Categories