Adding values to Jtable when button is clicked in java [duplicate] - java

In my application everything is distributed.
On a action, application retrieves data from DB and saves in ArrayList<T>.
I create an object of RelativeTableModel where I pass the ArrayList<T>.
public void RelationsClicked() {
ArrayList<Relation> data = myParent.dbOperation.getRelations();
RelativeTableModel tModel = new RelativeTableModel(data); // subclass of AbstractTableModel
myParent.SetBrowsePanelData(tModel);
myParent.SetMainPanel(CashAccountingView.BROWSEPANEL);
}
I have a BrowseListPanel class that has a JTable in JScrollPane. Its instance is already created in the main application.
I pass the model to BrowseListPanel and finally show the panel.
Code:
public void SetBrowsePanelData(AbstractTableModel tModel) {
browsePanel.setTModel(tModel);
}
// BrowseListPanel's Code
public void setTModel(AbstractTableModel tModel) {
this.tModel = tModel; // tModel = AbstractTableModel
}
// Show the Panel
public void SetMainPanel(String panel) {
activePanel = panel;
SetFontSize();
cards.show(mainPanel, panel);
mainPanel.revalidate();
mainPanel.repaint();
}
But I don't see the Table. I believe as the object of BrowseListPanel (containing the JTable) is already created & later the TableModel is added. So some sort of event should be fired in setTModel().
Am I right? If so, what event should be thrown and what should be its implementation.

Invoking setModel() on the table should be sufficient, but you might call fireTableStructureChanged() on the model explicitly as a way to help sort things out.
Also, verify that you are working on the event dispatch thread.
Addendum: Here's an sscce that shows the basic approach.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
/** #see http://stackoverflow.com/questions/8257148 */
public class SwapTableModel extends JPanel {
public SwapTableModel() {
final JTable table = new JTable(Model.Alpha.model);
table.setPreferredScrollableViewportSize(new Dimension(128, 32));
this.add(new JScrollPane(table));
final JComboBox combo = new JComboBox();
for (Model model : Model.values()) {
combo.addItem(model);
}
this.add(combo);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Model model = (Model) combo.getSelectedItem();
table.setModel(model.model);
}
});
}
private enum Model {
Alpha(), Beta();
private DefaultTableModel model;
private Model() {
Object[] data = {this.toString()};
this.model = new DefaultTableModel(data, 1);
model.addRow(data);
}
}
private void display() {
JFrame f = new JFrame("SwapTableModel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new SwapTableModel().display();
}
});
}
}

Related

Get the in-focus tab after closing a tab

In a JTabbedPane, I associated a custom-made Data object to each added tab. I also have a corresponding Metadata object that shows up in another panel when the tab is selected. The problem I have now is when a tab is closed, the metadata panel shows the metadata of the Data object in the tab that just gets closed. Ideally, I want the panel to show the metadata for the in-focus tab that the user sees. However, the act of closing a tab means the “selected tab” is the tab being closed, so tabpane.getSelectedIndex() would not work. How can I get the tab that is in focus after closing a tab? Thank you in advance!
Devil is in the detail, which you provided none.
I did a quick test and discovered that, ChangeListener is called before ContainerListener, which is a real pain, but, it was always reporting the correct index.
So, what you need to do is marry the two together, so that, both will update the meta data pane when they are called.
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("One", new TabPane(tabbedPane));
tabbedPane.addTab("Two", new TabPane(tabbedPane));
tabbedPane.addTab("Three", new TabPane(tabbedPane));
tabbedPane.addTab("Four", new TabPane(tabbedPane));
tabbedPane.addContainerListener(new ContainerListener() {
#Override
public void componentAdded(ContainerEvent e) {
}
#Override
public void componentRemoved(ContainerEvent e) {
System.out.println("Removed " + e.getChild());
}
});
tabbedPane.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
System.out.println(tabbedPane.getSelectedIndex());
}
});
JFrame frame = new JFrame();
frame.add(tabbedPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TabPane extends JPanel {
private JTabbedPane parent;
public TabPane(JTabbedPane parent) {
this.parent = parent;
setLayout(new GridBagLayout());
JButton btn = new JButton("Close");
add(btn);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
parent.remove(TabPane.this);
}
});
}
}
}

How to turn a regular class into MVC?

I am working on a MVC based off of the code that I will be providing. I am having issues because I am fairly new to the subject. I am able to make the view, but when it comes to making the model it is a little more complicated for me. I need some guidance on how to turn the following code into a MVC so I can practice and learn. I been at this for several hours and I decided to come here for help.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class SayHi extends JFrame implements MouseListener{
// components
protected JLabel helloLabel = new JLabel("Hello");
protected JTextField userInputTextField = new JTextField(20);
private JButton sayHiBtn = new JButton("Say Hi");
/** Constructor */
SayHi() {
//... Layout the components.
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(new JLabel("Enter your name"));
content.add(userInputTextField);
content.add(sayHiBtn);
content.add(helloLabel);
// Add a mouse listener to the button
sayHiBtn.addMouseListener(this);
//... finalize layout
this.setContentPane(content);
this.pack();
this.setTitle("Simple App - Not MVC");
// The window closing event should probably be passed to the
// Controller in a real program, but this is a short example.
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// Methods I am forced to implement because of the MouseListener
public void mouseClicked(MouseEvent e) {
helloLabel.setText("Hello " + userInputTextField.getText());
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mousePressed(MouseEvent e){
}
public void mouseReleased(MouseEvent e){
}
public static void main(String[] args){
SayHi s = new SayHi();
s.setVisible(true);
}
}
The View only controls the visuals, The Model only controls the data access and the Controller is in charge of the logic that glues the two.
You could split that class into 3 classes in order to make it a MVC.
All the Jpanel would be located in a View, in the Model you would have all your values, like setting a string to hello and such, while the controller needs to interact with both the Model and View.
private SayHiModel model;
private SayHiView view;
SayHiController(SayHiModel model, SayHiView view) {
this.model = model;
this.view = view;
this.model.setValue(model.INITIAL_VALUE);
view.totalTextField.setText(model.getValue());
//... Add listeners to the view.
view.addMultiplyListener(new MultiplyListener());
view.addClearListener(new ClearListener());
}
Just a little hint to get you going.
There isn't much of a model to work with.
Here's your example code, with one view class, one model class, and one controller class. The SayHi class is the view class. The SayHiModel class is the model class. The SayHiListener class is the controller class.
package com.ggl.testing;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class SayHi implements Runnable {
private JFrame frame;
private JLabel helloLabel;
private JTextField userInputTextField;
private SayHiModel model;
public static void main(String[] args) {
SwingUtilities.invokeLater(new SayHi());
}
public SayHi() {
this.model = new SayHiModel();
}
#Override
public void run() {
// ... Layout the components.
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(new JLabel("Enter your name: "));
userInputTextField = new JTextField(20);
content.add(userInputTextField);
JButton sayHiBtn = new JButton("Say Hi");
// Add a mouse listener to the button
sayHiBtn.addMouseListener(new SayHiListener(this, model));
content.add(sayHiBtn);
helloLabel = new JLabel("Hello");
content.add(helloLabel);
// ... finalize layout
frame = new JFrame("MVC App");
// The window closing event should probably be passed to the
// Controller in a real program, but this is a short example.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(content);
frame.pack();
frame.setVisible(true);
}
public JFrame getFrame() {
return frame;
}
public void setHelloLabel(String name) {
helloLabel.setText("Hello " + name);
}
public String getName() {
return userInputTextField.getText().trim();
}
public class SayHiModel {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class SayHiListener extends MouseAdapter {
private SayHi sayHi;
private SayHiModel sayHiModel;
public SayHiListener(SayHi sayHi, SayHiModel sayHiModel) {
this.sayHi = sayHi;
this.sayHiModel = sayHiModel;
}
#Override
public void mouseClicked(MouseEvent e) {
sayHiModel.setName(sayHi.getName());
sayHi.setHelloLabel(sayHiModel.getName());
JFrame frame = sayHi.getFrame();
frame.setVisible(false);
frame.pack();
frame.setVisible(true);
}
}
}

Adding a panel from a method to a frame

I didn't really know how else to phrase that but essentially:
-I have a few separate "pieces" that I am trying to add onto a master frame; to keep the code from getting unwieldy I have each "piece" be its own class.
-I'm getting stuck on adding the panells onto the master frame, because the classes themselves aren't panels, rather the method of the class creates the panel, which creates issues that I don't know how to solve.
PIECE (works on its own when I have it make a dialog instead of be a panel):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PieceThing3 extends JPanel //<switched from JDialog
{
//set up variables here
private ActionListener pieceAction = new ActionListener()
{
public void actionPerformed (ActionEvent ae)
{
// Action Listener (this also works)
}
};
private void createPiece()
{
//setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//setLocationByPlatform(true);
// the above are commented out when I switch from dialog to panel
JPanel contentPane = new JPanel();
//something that uses pieceAction is here
//two buttons, b and s, with action listeners are here
contentPane.add(b);
contentPane.add(s);
add(contentPane);
//pack();
//again, commented out to switch from dialog
setVisible(true);
System.out.println("hi I'm done");
//just to check and make sure it's done
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PieceThing3().createPiece();
}
});
}
}
Sorry that is very vague, but the intricacies are not as important as the general idea - it works perfectly when I have it create its own dialog box, but now I am trying to get it to make a panel within a master code, below:
MASTER:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CollectGUI extends JFrame{
private void createDialog(){
this.setSize(2000,1000);
this.setLocation(0,0);
this.setTitle("TITLE");
PieceThing3 pt = new PieceThing3();
//HERE, if I do pt.main(null); while it is in "dialog mode" (rather than panel) it pops up a dialog box and everything is hunky dory. But I don't know how to get it to add the method as a panel.
this.add(pt.main(null));
//this gives an error
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new CollectGUI().createDialog();
}
}
As I said in the comments, if I just do pt.main(null) when pt is set to make a dialog, it does it, but if I try to add pt.main(null) as a panel it throws an error. Can anybody give me some insight on how to add a method of a class rather than a class? I'm pretty stumped.
THANK YOU!!
You are definitely on the right track working to maintain separation of concerns and implement your gui in a number of distinct components. Try something like this:
Panel1
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
public Panel1() {
this.add(new JLabel("This is panel 1"));
}
}
Panel2
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Panel2 extends JPanel {
public Panel2() {
this.add(new JLabel("This is panel 2"));
}
}
JFrame
import java.awt.BorderLayout;
import javax.swing.JFrame;
import org.yaorma.example.jframe.panel.panel1.Panel1;
import org.yaorma.example.jframe.panel.panel2.Panel2;
public class ExampleJFrame extends JFrame {
public ExampleJFrame() {
super("Example JFrame Application");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400,400);
this.setLayout(new BorderLayout());
Panel1 pan1 = new Panel1();
Panel2 pan2 = new Panel2();
this.add(pan1, BorderLayout.NORTH);
this.add(pan2, BorderLayout.SOUTH);
this.setVisible(true);
}
}
main:
public class ExampleApplication {
public static void main(String[] args) throws Exception {
new ExampleJFrame();
}
}
EDIT:
Here's a Panel1 with a little more content.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.yaorma.example.action.sayhello.SayHelloAction;
public class Panel1 extends JPanel {
//
// instance variables
//
private JButton pressMeButton;
//
// constructor
//
public Panel1() {
this.setLayout(new BorderLayout());
this.add(new JLabel("This is panel 1"), BorderLayout.NORTH);
this.initPressMeButton();
}
//
// button
//
private void initPressMeButton() {
this.pressMeButton = new JButton("Press Me");
this.pressMeButton.addActionListener(new PressMeButtonActionListener());
this.add(pressMeButton, BorderLayout.SOUTH);
}
//
// method to get the parent jframe
//
private JFrame getParentJFrame() {
Container con = this;
while(con != null) {
con = con.getParent();
if(con instanceof JFrame) {
return (JFrame)con;
}
}
return null;
}
//
// action listener for Press Me button
//
private class PressMeButtonActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JFrame jFrame = getParentJFrame();
SayHelloAction action = new SayHelloAction(jFrame);
action.execute();
}
}
}
Action called by button:
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class SayHelloAction {
private JFrame owner;
public SayHelloAction(JFrame owner) {
this.owner = owner;
}
public void execute() {
JOptionPane.showMessageDialog(owner, "Hello World");
}
}

Needing to return value from user input

a basic problem that i can't figure out, tried a lot of things and can't get it to work, i need to be able to get the value/text of the variable
String input;
so that i can use it again in a different class in order to do an if statement based upon the result
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class pInterface extends JFrame {
String input;
private JTextField item1;
public pInterface() {
super("PAnnalyser");
setLayout(new FlowLayout());
item1 = new JTextField("enter text here", 10);
add(item1);
myhandler handler = new myhandler();
item1.addActionListener(handler);
System.out.println();
}
public class myhandler implements ActionListener {
// class that is going to handle the events
public void actionPerformed(ActionEvent event) {
// set the variable equal to empty
if (event.getSource() == item1)// find value in box number 1
input = String.format("%s", event.getActionCommand());
}
public String userValue(String input) {
return input;
}
}
}
You could display the window as a modal JDialog, not a JFrame and place the obtained String into a private field that can be accessed via a getter method. Then the calling code can easily obtain the String and use it. Note that there's no need for a separate String field, which you've called "input", since we can easily and simply extract a String directly from the JTextField (in our "getter" method).
For example:
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.*;
import javax.swing.text.JTextComponent;
public class TestPInterface {
#SuppressWarnings("serial")
private static void createAndShowGui() {
final JFrame frame = new JFrame("TestPInterface");
// JDialog to hold our JPanel
final JDialog pInterestDialog = new JDialog(frame, "PInterest",
ModalityType.APPLICATION_MODAL);
final MyPInterface myPInterface = new MyPInterface();
// add JPanel to dialog
pInterestDialog.add(myPInterface);
pInterestDialog.pack();
pInterestDialog.setLocationByPlatform(true);
final JTextField textField = new JTextField(10);
textField.setEditable(false);
textField.setFocusable(false);
JPanel mainPanel = new JPanel();
mainPanel.add(textField);
mainPanel.add(new JButton(new AbstractAction("Get Input") {
#Override
public void actionPerformed(ActionEvent e) {
// show dialog
pInterestDialog.setVisible(true);
// dialog has returned, and so now extract Text
textField.setText(myPInterface.getText());
}
}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
// by making the class a JPanel, you can put it anywhere you want
// in a JFrame, a JDialog, a JOptionPane, another JPanel
#SuppressWarnings("serial")
class MyPInterface extends JPanel {
// no need for a String field since we can
// get our Strings directly from the JTextField
private JTextField textField = new JTextField(10);
public MyPInterface() {
textField.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
JTextComponent textComp = (JTextComponent) e.getSource();
textComp.selectAll();
}
});
add(new JLabel("Enter Text Here:"));
add(textField);
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window win = (Window) SwingUtilities.getWindowAncestor(MyPInterface.this);
win.dispose();
}
});
}
public String getText() {
return textField.getText();
}
}
A Good way of doing this is use Callback mechanism.
I have already posted an answer in the same context.
Please find it here JFrame in separate class, what about the ActionListener?.
Your method is a bit confusing:
public String userValue(String input) {
return input;
}
I guess you want to do something like this:
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
Also your JFrame is not visible yet. Set the visibility like this setVisible(true)

Display the item name on the table in a JLabel

I want to put the name of the item that I selected in a JTable in a JLabel that every time that i click a new item in the table the text in the JLabel also change
can someone tell me what should I learn in java to produce that?
You should know very basic Swing programming, and a little deeper understanding of a TableModel, SelectionModel and ListSelectionListener (which is the key to your goal).
A working example:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class TableSelectionToLabel {
private static JTable t = new JTable(new String[][]{{"1,1", "1,2"}, {"2,1", "2,2"}},
new String[]{"1", "2"});
private static JLabel l = new JLabel("Your selction will appear here");
private static JFrame f = new JFrame("Table selection listener Ex.");
private static ListSelectionListener myListener = new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
int col = t.getColumnModel().getSelectionModel().getLeadSelectionIndex();
int row = t.getSelectionModel().getLeadSelectionIndex();
try {
l.setText(t.getModel().getValueAt(row, col).toString());
} catch (IndexOutOfBoundsException ignore) {
}
}
};
public static void main(String[] args) {
t.getSelectionModel().addListSelectionListener(myListener);
t.getColumnModel().getSelectionModel().addListSelectionListener(myListener);
f.getContentPane().add(t, BorderLayout.NORTH);
f.getContentPane().add(l, BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
}
EDIT:
I modified the code to listen to both selection events from the model AND the column model to get a more accurate outcome.
First create the JLabel:
JLabel label = new JLabel();
Then add a listener to the table for selections:
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
label.setText(table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()));
}
});

Categories

Resources