Scrollbar not getting created/ table not shown - java

I'm writing a program where there is a JTable to be created (Which I'm able to). But I want to add a scroll bar to it. Below is my code.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
public class TagReplaceUI extends JFrame {
private JPanel contentPane;
private JTextField srcTextField;
private Executor executor = Executors.newCachedThreadPool();
static DefaultTableModel model = new DefaultTableModel();
static JTable table = new JTable(model);
/**
* Launch the application.
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
final TagReplaceUI frame = new TagReplaceUI();
frame.add(new JScrollPane(table));
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
// FileDownloadTest downloadTest = new
// FileDownloadTest(srcTextField.getText(), textArea);
public TagReplaceUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 552, 358);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
srcTextField = new JTextField();
srcTextField.setBounds(10, 26, 399, 20);
contentPane.add(srcTextField);
srcTextField.setColumns(10);
JButton srcBtn = new JButton("Source Excel");
srcBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fChoose = new JFileChooser();
fChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (fChoose.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
srcTextField.setText(fChoose.getSelectedFile().getAbsolutePath());
} else {
System.out.println("No Selection");
}
}
});
table.setBounds(10, 131, 516, 178);
contentPane.add(table);
model.addColumn("Col1");
model.addColumn("Col2");
srcBtn.setBounds(419, 25, 107, 23);
contentPane.add(srcBtn);
JButton dNcButton = new JButton("Process");
dNcButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
executor.execute(new Test(srcTextField.getText(), model));
}
});
dNcButton.setBounds(212, 70, 89, 23);
contentPane.add(dNcButton);
}
}
When I run the above program, the table frame is also not displayed. But when I remove frame.add(new JScrollPane(table));, it is displaying the table in the JTable area, but there is no scrollbar in it.
Please let me know how can I get a scrollbar in the table and display the data correctly.
Thanks

At first don't use null layout, please read here.
frame.add(new JScrollPane(table)); this scroll pane is not displaying because in null layout each component needs to have bounds. Try below code. I just changed static variables to instance variables. And added scrollpane in to the constructor.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
public class TagReplaceUI extends JFrame {
private JPanel contentPane;
private JTextField srcTextField;
private Executor executor = Executors.newCachedThreadPool();
private DefaultTableModel model = new DefaultTableModel();
private JTable table = new JTable(model);
/**
* Launch the application.
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
final TagReplaceUI frame = new TagReplaceUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
// FileDownloadTest downloadTest = new
// FileDownloadTest(srcTextField.getText(), textArea);
public TagReplaceUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 552, 358);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
srcTextField = new JTextField();
srcTextField.setBounds(10, 26, 399, 20);
contentPane.add(srcTextField);
srcTextField.setColumns(10);
JButton srcBtn = new JButton("Source Excel");
srcBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fChoose = new JFileChooser();
fChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (fChoose.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
srcTextField.setText(fChoose.getSelectedFile().getAbsolutePath());
} else {
System.out.println("No Selection");
}
}
});
JScrollPane scroll = new JScrollPane(table);
scroll.setBounds(10, 131, 516, 178);
contentPane.add(scroll);
model.addColumn("Col1");
model.addColumn("Col2");
srcBtn.setBounds(419, 25, 107, 23);
contentPane.add(srcBtn);
JButton dNcButton = new JButton("Process");
dNcButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
executor.execute(new Test(srcTextField.getText(), model));
}
});
dNcButton.setBounds(212, 70, 89, 23);
contentPane.add(dNcButton);
}
}

Related

Long text scroll in JFrame

I am building this program and I would like to have a square area that is scrollable since the text is long. I've tried some methods but it seems to cut out the text out of the length. Could anyone give me a tip on how to do this?
package gerador;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.Scrollable;
public class frameMyPasswords extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frameMyPasswords frame = new frameMyPasswords();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public frameMyPasswords() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JTextArea txtField = new JTextArea();
txtField.setLineWrap(true);
txtField.setEditable(false);
txtField.setToolTipText("");
txtField.setBounds(10, 38, 419, 144);
txtField.setText("LONG TEXT");
contentPane.add(txtField);
}
}

How to add a JButton to a JFrame?

I tried to add a button to the JFrame, but it won't appear for some reason. How do I make it appear?
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Container;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.*;
public class GraficoconArreglo extends javax.swing.JFrame {
JPanel pan = (JPanel) this.getContentPane();
JLabel []lab = new JLabel[6];
JTextField []text = new JTextField[6];
Border border = BorderFactory.createLineBorder(Color.pink,1);
JButton b = new JButton("Calculate");
public GraficoconArreglo() {
initComponents();
pan.setLayout(null);
pan.setBackground(Color.GRAY);
for(int i=0; i<lab.length ;i++){
lab[i] = new JLabel();
text[i] = new JTextField();
lab[i].setBounds(new Rectangle(15,(i+1)*40, 60, 25));
lab[i].setText("Data " + (i+1));
lab[i].setBorder(border);
text[i].setBounds(new Rectangle(100,(i+1)*40, 60, 25));
pan.add(lab[i],null);
pan.add(text[i],null);
setSize(200,330);
setTitle("Arrays in forums.");
add(b);
b.addActionListener((ActionListener) this);
}
}
You are creating only one button and adding it to 6 different places. Therefore, you only would see it on the last place you added.
You should add the button to the contentPane, not the JFrame. A working code for this, provided from SwingDesigner from Eclipse Marketplace would be:
public class Window extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Window frame = new Window();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Window() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
setContentPane(contentPane);
JButton btnNewButton = new JButton("New button");
btnNewButton.setBounds(170, 110, 89, 23);
contentPane.add(btnNewButton);
}
}

How to add some row's specific info to JTexFields using MySQL

I have been trying to add a table rows' info to JTextField components after clicking with the mouse however it doesn't work. I have used the DefaultTableModel and JTable as shown below.
Here is the code I have been using.
package scrCode;
import java.util.*;
import java.sql.*;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import net.proteanit.sql.DbUtils;
import javax.swing.JTable;
import javax.swing.JLabel;
import java.awt.Font;
import javax.swing.SwingConstants;
import javax.swing.JButton;
import java.awt.SystemColor;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JComboBox;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class BorrowABook extends JFrame {
private JPanel contentPane;
private JTable table;
private JButton button;
private JLabel lblBookId;
private JTextField textFieldBookID;
private JLabel lblMemberId;
private JTextField textFieldMemberID;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BorrowABook frame = new BorrowABook();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public BorrowABook() {
setTitle("Library system");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 971, 594);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
String data [][]=null;
String column []=null;
DefaultTableModel model = new DefaultTableModel();
try {
//code to receive data from the database
Connection con=DB.login();
PreparedStatement ps=con.prepareStatement("select * from book",ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet rs=ps.executeQuery();
ResultSetMetaData rsmd=rs.getMetaData();
int cols=rsmd.getColumnCount();
column=new String[cols];
for(int i=1;i<=cols;i++){
column[i-1]=rsmd.getColumnName(i);
}
rs.last();
int rows=rs.getRow();
rs.beforeFirst();
data=new String[rows][cols];
int count=0;
while(rs.next()){
for(int i=1;i<=cols;i++){
data[count][i-1]=rs.getString(i);
}
count++;
}
con.close();
}catch (Exception e){
System.out.println(e);
}
contentPane.setLayout(null);
table = new JTable(data,column);
JScrollPane sp = new JScrollPane(table);
sp.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
int selectedRowIndex = table.getSelectedRow();
textFieldBookID.setText(model.getValueAt(selectedRowIndex, 0).toString());
textFieldMemberID.setText(model.getValueAt(selectedRowIndex, 1).toString());
}
});
sp.setBounds(5, 5, 936, 402);
contentPane.add(sp);
button = new JButton("Back");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
UserSection.main(new String [] {});
dispose();
}
});
button.setForeground(Color.BLACK);
button.setBackground(SystemColor.info);
button.setBounds(856, 509, 85, 25);
contentPane.add(button);
lblBookId = new JLabel("Book ID:");
lblBookId.setHorizontalAlignment(SwingConstants.RIGHT);
lblBookId.setFont(new Font("Sitka Display", Font.BOLD, 22));
lblBookId.setBounds(28, 420, 141, 29);
contentPane.add(lblBookId);
textFieldBookID = new JTextField();
textFieldBookID.setColumns(10);
textFieldBookID.setBounds(181, 420, 257, 29);
contentPane.add(textFieldBookID);
lblMemberId = new JLabel("Memeber ID:");
lblMemberId.setHorizontalAlignment(SwingConstants.RIGHT);
lblMemberId.setFont(new Font("Sitka Display", Font.BOLD, 22));
lblMemberId.setBounds(28, 469, 141, 29);
contentPane.add(lblMemberId);
textFieldMemberID = new JTextField();
textFieldMemberID.setColumns(10);
textFieldMemberID.setBounds(181, 469, 257, 29);
contentPane.add(textFieldMemberID);
}
}
Suggestions:
Add your MouseListener to your JTable, not to the JScrollPane. You need notification for when the table has been clicked.
You're using the wrong model in your listener as you never fill the DefaultTableModel with data. Be safe and get the model in the listener via table.getModel()
No null layouts. While this is not causing your current problem, it forces you to code against the library rather than with it.
For example (database code removed for simplicity, null layout removed as well, and posted a MCVE):
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
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.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
public class BorrowABook extends JFrame {
private JPanel contentPane;
private JTable table;
private JButton button;
private JLabel lblBookId;
private JTextField textFieldBookID;
private JLabel lblMemberId;
private JTextField textFieldMemberID;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BorrowABook frame = new BorrowABook();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public BorrowABook() {
setTitle("Library system");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 971, 594);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
String data[][] = {{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}};
String column[] = {"One", "Two", "Three" };
DefaultTableModel model = new DefaultTableModel();
// !! contentPane.setLayout(null);
contentPane.setLayout(new BorderLayout());
table = new JTable(data, column);
JScrollPane sp = new JScrollPane(table);
table.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
int selectedRowIndex = table.getSelectedRow();
textFieldBookID.setText(table.getModel().getValueAt(selectedRowIndex, 0).toString());
textFieldMemberID.setText(table.getModel().getValueAt(selectedRowIndex, 1).toString());
}
});
//!! sp.setBounds(5, 5, 936, 402);
contentPane.add(sp);
JPanel bottomPanel = new JPanel();
lblBookId = new JLabel("Book ID:");
lblBookId.setHorizontalAlignment(SwingConstants.RIGHT);
lblBookId.setFont(new Font("Sitka Display", Font.BOLD, 22));
bottomPanel.add(lblBookId);
textFieldBookID = new JTextField();
textFieldBookID.setColumns(10);
textFieldBookID.setBounds(181, 420, 257, 29);
bottomPanel.add(textFieldBookID);
lblMemberId = new JLabel("Memeber ID:");
lblMemberId.setHorizontalAlignment(SwingConstants.RIGHT);
lblMemberId.setFont(new Font("Sitka Display", Font.BOLD, 22));
lblMemberId.setBounds(28, 469, 141, 29);
bottomPanel.add(lblMemberId);
textFieldMemberID = new JTextField();
textFieldMemberID.setColumns(10);
textFieldMemberID.setBounds(181, 469, 257, 29);
bottomPanel.add(textFieldMemberID);
contentPane.add(bottomPanel, BorderLayout.PAGE_END);
}
}

How to open a new JPanel with a JButton?

I am trying to code a program with multiple screens, however, I do not want to use tabbed panes. I have looked at using multiple JPanels with the card layout and the methods are simply not working. What I need to be able to do is load the new JPanel when a button is clicked. Here is my code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.CardLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class IA extends JFrame {
private JPanel contentPane;
private JPanel home;
private JPanel clients;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
IA frame = new IA();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public IA() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new CardLayout(0, 0));
JPanel home = new JPanel();
contentPane.add(home, "name_714429679706141");
home.setLayout(null);
JButton btnClients = new JButton("Clients");
btnClients.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
home.setVisible(false);
clients.setVisible(true);
}
});
btnClients.setBounds(160, 108, 89, 23);
home.add(btnClients);
JPanel clients = new JPanel();
contentPane.add(clients, "name_714431450350356");
clients.setLayout(null);
JButton btnHome = new JButton("Home");
btnHome.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
clients.setVisible(false);
home.setVisible(true);
}
});
btnHome.setBounds(169, 107, 89, 23);
clients.add(btnHome);
}
}
The problem is that you have duplicate variables home and clients .
The folllowing is your modified code to fix that, with comments on the changed lines (five lines total) :
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class IA extends JFrame {
private final JPanel contentPane;
// private final JPanel home; // REMOVED
// private JPanel clients; // REMOVED
/**
* Launch the application.
*/
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
IA frame = new IA();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public IA() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new CardLayout(0, 0));
final JPanel home = new JPanel();
contentPane.add(home, "name_714429679706141");
home.setLayout(null);
final JPanel clients = new JPanel(); // MOVED UP
contentPane.add(clients, "name_714431450350356"); // MOVED UP
clients.setLayout(null); // MOVED UP
JButton btnClients = new JButton("Clients");
btnClients.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
home.setVisible(false);
clients.setVisible(true);
}
});
btnClients.setBounds(160, 108, 89, 23);
home.add(btnClients);
JButton btnHome = new JButton("Home");
btnHome.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
clients.setVisible(false);
home.setVisible(true);
}
});
btnHome.setBounds(169, 107, 89, 23);
clients.add(btnHome);
}
}
I would take a look at this post, however I have a feeling you'll need to use a actionlistener to get this done...
Java Swing. Opening a new JPanel from a JButton and making the buttons pretty
I would of left this as a comment but apparently you need 50 rep for that...
This link might be more helpful.. How to open a new window by clicking a button
When the following code is invoked the clients variable equals to null.
JButton btnClients = new JButton("Clients");
btnClients.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
home.setVisible(false);
clients.setVisible(true);
}
});
Write this:
JPanel clients = new JPanel();
contentPane.add(clients, "name_714431450350356");
clients.setLayout(null);
JButton btnHome = new JButton("Home");
btnHome.setBounds(169, 107, 89, 23);
clients.add(btnHome);
before you add the Action Listener

Java Component not showing on startup

I have a Class that adds an ImageIcon in the East of a TextField if you pass it to that Class, it's working pretty good during runtime if I press a Button to change frames, but the Image is not showing up at the startup.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class TestStartFrame extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
TestStartFrame frame = new TestStartFrame();
frame.setVisible(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TestStartFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.CENTER);
btnNewButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
SecondFrame fr = new SecondFrame();
fr.setVisible(true);
try
{
int r = 250;
int g = 250;
int b = 250;
UIManager.put("control", new Color(r, g, b));
UIManager
.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.put("control", new Color(r, g, b));
SwingUtilities
.updateComponentTreeUI(SecondFrame.contentPane);
} catch (Exception e1)
{
System.out.println(e1.getMessage());
}
dispose();
}
});
}
}
class SecondFrame extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 1L;
public final static JPanel contentPane = new JPanel();
/**
* Create the frame.
*/
public SecondFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout());
JTextField txt = new JTextField();
contentPane.add(txt, BorderLayout.CENTER);
txt = ClearImage.addImage(txt);
}
}
class ClearImage
{
public static JTextField addImage(final JTextField comp)
{
Image image = new BufferedImage(10, 25, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 10, 25);
graphics.setColor(Color.LIGHT_GRAY);
graphics.fillOval(0, 7, 10, 10);
graphics.setColor(Color.GRAY);
graphics.drawLine(2, 9, 8, 15);
graphics.drawLine(2, 15, 8, 9);
JLabel lblClear = new JLabel(new ImageIcon(image));
comp.setLayout(new BorderLayout());
comp.add(lblClear, BorderLayout.EAST);
lblClear.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
lblClear.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
comp.setText("");
}
});
return comp;
}
public static JTextField removeImage(final JTextField comp)
{
comp.removeAll();
return comp;
}
}
If I place the UI change before the Frame visible, I don't have that problem, could anyone explain me why is it that way?
Your problem is caused by the change of UI factory on the JTextField (this is triggered by the installation of the Nimbus L&F and the updateComponentTreeUI()).
When you do that the second call, you automatically uninstall the previous L&F and UI factory of the JTextField. By default, this is Metal L&F Text UI (MetalTextFieldUI) which extends BasicTextUI. This invokes the method javax.swing.plaf.basic.BasicTextUI.uninstallUI(JComponent) and its content is the following:
public void uninstallUI(JComponent c) {
// detach from the model
editor.removePropertyChangeListener(updateHandler);
editor.getDocument().removeDocumentListener(updateHandler);
// view part
painted = false;
uninstallDefaults();
rootView.setView(null);
c.removeAll();
LayoutManager lm = c.getLayout();
if (lm instanceof UIResource) {
c.setLayout(null);
}
// controller part
uninstallKeyboardActions();
uninstallListeners();
editor = null;
}
Notice the call c.removeAll() which basically removes your label from the hierarchy and hence causes the issue you are seeing.
Arguably, we could say that adding components to primitive Swing widgets is not ideal and this is not how they were intended to be used. I personally find that argument quite weak, but I know that many Swing lovers are found of it.
Simply make sure to do the update of the UI before adding your JLabel or extends JTextField and upon update of the UI, re-install your JLabel in the JTextField.
Small example (just to demo my explanation):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class TestAddImageToTextField {
private static class MyJTextField extends JTextField {
#Override
public void updateUI() {
removeAll();
super.updateUI();
Image image = buildImage();
JLabel lblClear = new JLabel(new ImageIcon(image));
lblClear.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
MyJTextField.this.setText("");
}
});
setLayout(new BorderLayout());
add(lblClear, BorderLayout.EAST);
}
private Image buildImage() {
Image image = new BufferedImage(10, 25, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 10, 25);
graphics.setColor(Color.LIGHT_GRAY);
graphics.fillOval(0, 7, 10, 10);
graphics.setColor(Color.GRAY);
graphics.drawLine(2, 9, 8, 15);
graphics.drawLine(2, 15, 8, 9);
return image;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
TestAddImageToTextField frame = new TestAddImageToTextField();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private JComponent contentPane;
/**
* Create the frame.
*
* #throws UnsupportedLookAndFeelException
* #throws IllegalAccessException
* #throws InstantiationException
* #throws ClassNotFoundException
*/
public TestAddImageToTextField() throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 450, 300);
contentPane = (JComponent) frame.getContentPane();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
MyJTextField comp = new MyJTextField();
contentPane.add(comp);
frame.setVisible(true);
installNimbusLAF();
}
private void installNimbusLAF() throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
int r = 250;
int g = 250;
int b = 250;
UIManager.put("control", new Color(r, g, b));
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.put("control", new Color(r, g, b));
SwingUtilities.updateComponentTreeUI(contentPane);
}
}

Categories