I have some problem to put lines in row header of my custom JTable.
I create this JTable with this code:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
public class Form {
public static void main(String[] args) {
JFrame frame = new JFrame();
List<String> visibleColumns = new ArrayList<String>();
// THIS COLUMN NEED TO BE IN 2 LINES
visibleColumns.add("Cod Type\nGroup");
visibleColumns.add("Name");
DefaultTableModel tableModel = new DefaultTableModel(visibleColumns.toArray(),5);
JTable table = new JTable(tableModel);
Panel panel = new Panel();
panel.setBounds(5, 5, 352, 232);
panel.setLayout(new BorderLayout());
panel.add(table, BorderLayout.CENTER);
panel.add(table.getTableHeader(), BorderLayout.NORTH);
// Set Row Header
JScrollPane scroll = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Set Column Header
JPanel columnHeader = new JPanel() {
#Override
public Dimension getPreferredSize() {
JScrollBar sb = new JScrollBar(JScrollBar.VERTICAL);
return new Dimension(sb.getPreferredSize().width, 10);
}
};
scroll.setRowHeaderView(columnHeader);
// Set 3D effects to scroll pane
JPanel left = new JPanel();
left.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
scroll.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, left);
JPanel right = new JPanel();
right.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
scroll.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, right);
panel.add(scroll, BorderLayout.CENTER);
//Setting column size
TableColumnModel tcm = table.getColumnModel();
tcm.getColumn(0).setMaxWidth(Integer.MAX_VALUE);
tcm.getColumn(0).setWidth(73);
tcm.getColumn(0).setPreferredWidth(73);
tcm.getColumn(1).setMaxWidth(Integer.MAX_VALUE);
tcm.getColumn(1).setWidth(222);
tcm.getColumn(1).setPreferredWidth(222);
frame.add(panel);
frame.setSize(350, 180);
frame.setVisible(true);
}
}
But I need that the text "Cod Type\nGroup" create a new line row header, like this figure:
Ps: Note that the text is centered.
Thanks
You can use HTML like this
visibleColumns.add("<html><center>Cod Type<br>Group");
visibleColumns.add("Name");
And also take a look at Layout Managers because swing is designed to use them instead of null layouts.
Related
*edited so it might be helpful to others:
I was struggling with why an ImageIcon was being padded in a JPanel, but not in a JToolBar even though they were added in the same way, using the same file (see the folder icon):
Cutting down the code to an sscce has shown that VGR's answer below is right - it's has to be how each component deals with JButtons, rather than the layout.
This code should run, but you'll have to have "images/open.png" in the source folder.
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.border.Border;
class CandidatePanel extends JPanel{
private JPanel panel = new JPanel();
private JToolBar tb = new JToolBar();
private JButton tbButton = new JButton();
private JButton cvButton = new JButton();
public static void main(String[] args){
JFrame frame = new JFrame();
frame.add(new CandidatePanel());
frame.pack();
frame.setVisible(true);
}
public CandidatePanel(){
setLayout(new GridBagLayout());
tbButton.setIcon(new PanelHelper().createIcon("images/open.png", ""));
tb.add(tbButton);
cvButton.setIcon(new PanelHelper().createIcon("images/open.png", ""));
cvButton.setFocusPainted(false);
cvButton.setContentAreaFilled(false);
cvButton.setBorderPainted(true);
addComponents();
add(tb);
add(panel);
}
private void addComponents(){
panel.setLayout(new GridBagLayout());
int row =0;
//new row
JPanel cvButtonPanel = (JPanel)PanelHelper.addTestBorder(new JPanel(),Color.BLUE);
cvButtonPanel.add(cvButton);
cvButtonPanel.add(PanelHelper.addTestBorder(new JPanel(), Color.RED));
panel.add(tb, new GBC(1,row));
panel.add(cvButtonPanel, new GBC(1,++row));
}
}
class PanelHelper{
public static JComponent addTestBorder(JComponent comp, Color color){
Border border = BorderFactory.createLineBorder(color);
comp.setBorder(border);
return comp;
}
public ImageIcon createIcon(String path, String btnName){
URL url = getClass().getResource(path);
if(url == null)
System.err.println("\nThe "+btnName+" Icon Path Cannot Be Found: "+path);
return new ImageIcon(url);
}
}
it was just as simple as setting the button margin, as mentioned in the comments below.
button.setMargin(new Insets(0,0,0,0))
I'm using a tabbed pane and can't get the tab to show the GUI that I want. I plan to have different Panel objects for each different tab so that I can setup their layouts with more versatility. Right now I don't have any listeners or functions, and am strictly trying to get the components to show up.
Edit: Code is now in the question, not a link.
Here is the code for the UI for the "General":
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
public class GeneralGUI extends JPanel{
public GeneralGUI() {
JPanel topPanel = new JPanel();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JLabel subjectNum = new JLabel("Subject Street #:");
JLabel subjectStreet = new JLabel("Subject Street Name:");
JTable compTable = new JTable();
JTable subjectTable = new JTable();
JButton getRPT = new JButton("Get RPT file");
JButton getOrder = new JButton("Get Order/Contract");
JButton subjectDocs = new JButton("Get Subject Docs");
JButton compDocs = new JButton("Get Comp Docs");
panel1.add(subjectNum);
panel1.add(subjectStreet);
panel1.add(compTable);
panel2.add(getRPT);
panel2.add(getOrder);
panel2.add(subjectDocs);
panel2.add(compDocs);
panel2.add(subjectTable);
topPanel.add(panel1);
topPanel.add(panel2);
topPanel.setVisible(true);
}
}
Here is the code for the tabbed pane code:
import javax.swing.JTabbedPane;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
public class AppraisalTabs extends JPanel {
public AppraisalTabs() {
super(new GridLayout(1, 1));
JTabbedPane tabbedPane = new JTabbedPane();
GeneralGUI genGUI = new GeneralGUI();
// JComponent panel1 = makeTextPanel("General");
tabbedPane.addTab("General", genGUI);
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
JComponent panel2 = makeTextPanel("Docs");
tabbedPane.addTab("Docs", panel2);
tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
JComponent panel3 = makeTextPanel("Subject");
tabbedPane.addTab("Subject", panel3);
tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);
JComponent panel4 = makeTextPanel("Comps");
panel4.setPreferredSize(new Dimension(410, 300));
tabbedPane.addTab("Comps", panel4);
tabbedPane.setMnemonicAt(3, KeyEvent.VK_4);
JComponent panel5 = makeTextPanel("Report");
panel4.setPreferredSize(new Dimension(800, 800));
tabbedPane.addTab("Report", panel5);
tabbedPane.setMnemonicAt(4, KeyEvent.VK_5);
//Add the tabbed pane to this panel.
add(tabbedPane);
//The following line enables to use scrolling tabs.
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
}
protected JComponent makeTextPanel(String text) {
JPanel panel = new JPanel(false);
JLabel filler = new JLabel(text);
filler.setHorizontalAlignment(JLabel.CENTER);
panel.setLayout(new GridLayout(1, 1));
panel.add(filler);
return panel;
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Appraisal Helper");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add content to the window.
frame.add(new AppraisalTabs(), BorderLayout.CENTER);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
}
My problem is that once I run the code the tabbed pane shows up, as well as the correctly-titled tabs, but the "General" tab isn't showing anything at all. I tried to setup the buttons and everything in it but it's still blank.
Any ideas?
JPanel panel = new JPanel(new GridLayout(0,1));
JScrollPane contentpane = new JScrollPane(panel);
JButton add = new JButton("ADD");
add.actionListener(new ActionListener() {
public void actionPerformed(){
MyPanel newpanel = new MyPanel("title","Button"); //MyPanel is a class which extends JPanel and contains constructor MyPanel(String TitleToSet ,String ButtonTitleTOAdd)
panel.add(newpanel);
panel.repaint();
}) ;
I have used this code thinking that it will add the MyPanel to the grid layout dynamically and "panel" would be scrollable if more "MyPanel"s are added. However, this was not the case, 1st "MyPanel" filled whole "panel" and on adding second "MyPanel" (by clicking button "Add"), the 1st "MyPanel" was shrinked to make space for second one to be added.. and on adding more, all the "MyPanel"s were fit in the viewport instead of making the "panel" scrollable.. How to add those "MyPanel"s dynamically and making the "panel" scrollable on adding more of those?? Any help would be appreciated.
http://docs.oracle.com/javase/7/docs/api/javax/swing/JScrollPane.html :
By default JScrollPane uses ScrollPaneLayout to handle the layout of
its child Components. ScrollPaneLayout determines the size to make the
viewport view in one of two ways:
[...]
getPreferredSize is used.
You should add the line
panel.setPreferredSize(new Dimension(0, panel.getComponents().size() * SUB_PANEL_HEIGHT));
to your ActionListener.
Full example:
package main;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Panel;
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 javax.swing.JScrollPane;
import javax.swing.Timer;
class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(400, 400));
frame.setSize(400, 400);
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(new JLabel("BOO"));
panel.add(new JButton("BBBB"));
JScrollPane contentpane = new JScrollPane(panel);
frame.add(contentpane);
new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel newpanel = new JPanel();
newpanel.add(new JLabel("LOL"));
panel.add(newpanel);
System.out.println(100 * panel.getComponents().length);
panel.setPreferredSize(new Dimension(0, 100 * panel.getComponents().length));
contentpane.validate();
}
}).start();
frame.setVisible(true);
}
}
I created a JTable using the code:
List<String> visibleColumns = new ArrayList<String>();
visibleColumns.add("Column 1");
visibleColumns.add("Column 2");
visibleColumns.add("Column 3");
DefaultTableModel tableModel = new DefaultTableModel(visibleColumns.toArray(),100);
JTable table = new JTable(tableModel);
JPanel panel = new SwingPaneTable();
panel.setBounds(0, 0, 280, 150);
panel.setLayout(new BorderLayout());
panel.add(table, BorderLayout.CENTER);
panel.add(table.getTableHeader(), BorderLayout.NORTH);
// Set Row Header
JList<String> rowHeader = new JList<String>();
rowHeader.setFixedCellWidth(18);
rowHeader.setFixedCellHeight(18);
rowHeader.setBackground(panel.getBackground());
rowHeader.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
JScrollPane scroll = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
scroll.setRowHeaderView(rowHeader);
panel.add(scroll, BorderLayout.CENTER);
And the table looks like that:
Now, I need to add this effects im my table:
Someone knows how I do this in this code?
You seem to be going to a lot of effort which doesn't seem to be required (IMHO)...
JScrollPane provides you with the means to add corners to each of the corner of the scroll pane as well as provide row and column headers...
See http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html
In the case of JTable, it applies the JTableHeader to the JScrollPane's column header area automatically.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.MatteBorder;
import javax.swing.table.DefaultTableModel;
public class TableExample {
public static void main(String[] args) {
new TableExample();
}
public TableExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
List<String> visibleColumns = new ArrayList<String>();
visibleColumns.add("Column 1");
visibleColumns.add("Column 2");
visibleColumns.add("Column 3");
DefaultTableModel tableModel = new DefaultTableModel(visibleColumns.toArray(), 100);
JTable table = new JTable(tableModel);
JScrollPane scroll = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JPanel left = new JPanel();
left.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
scroll.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, left);
JPanel right = new JPanel();
right.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
scroll.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, right);
JPanel columnHeader = new JPanel() {
#Override
public Dimension getPreferredSize() {
JScrollBar sb = new JScrollBar(JScrollBar.VERTICAL);
return new Dimension(sb.getPreferredSize().width, 10);
}
};
columnHeader.setBorder(new CompoundBorder(
new MatteBorder(1, 1, 0, 0, Color.WHITE),
new MatteBorder(0, 0, 1, 1, Color.GRAY)
));
scroll.setRowHeaderView(columnHeader);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(scroll);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I am developing a Java application and would like some help in positioning some Labels and TextFields.
Here is my code:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComboBox;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.FlowLayout;
public class AuctionClient
{
public AuctionClient()
{
JFrame GUIFrame = new JFrame();
JPanel GUIPanel = new JPanel();
JLabel LabelUserName = new JLabel("UserName:");
JTextField TextFieldUserName = new JTextField(" ");
JLabel LabelPassword = new JLabel("Password:");
JTextField TextFieldPassword = new JTextField(" ");
GUIFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUIFrame.setTitle("Auction Client");
GUIFrame.setSize(500,250);
GUIFrame.setLocationRelativeTo(null);
GUIPanel.add(LabelUserName);
GUIPanel.add(TextFieldUserName);
GUIPanel.add(LabelPassword);
GUIPanel.add(TextFieldPassword);
GUIFrame.add(GUIPanel, BorderLayout.NORTH);
GUIFrame.setVisible(true);
}
}
With the above code, the LabelPassword and TextFieldPassword is on the same line as the LabelUsername and TextFieldUsername. Can I please have some help to position the LabelPassword and TextFieldPassword on a new line. Is it possible to specify X,Y coordinates to position objects on a JFrame?
Here is an image to show you how the objects are currently being shown:
http://canning.co.nz/Java/Positioning_Image.png
You should never try to position components with coordinates. Rather use appropriate LayoutManager's and use logical conditions and constraints to position your components.
Here is one example using GridBagLayout:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class AuctionClient {
public AuctionClient() {
JFrame guiFrame = new JFrame();
JPanel guiPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("UserName:");
JTextField userNameTextField = new JTextField(30);
JLabel passwordLabel = new JLabel("Password:");
JTextField passwordTextField = new JPasswordField(30);
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Auction Client");
guiFrame.setSize(500, 250);
guiFrame.setLocationRelativeTo(null);
GridBagConstraints labelGBC = new GridBagConstraints();
labelGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints fieldGBC = new GridBagConstraints();
fieldGBC.insets = new Insets(3, 3, 3, 3);
fieldGBC.gridwidth = GridBagConstraints.REMAINDER;
guiPanel.add(userNameLabel, labelGBC);
guiPanel.add(userNameTextField, fieldGBC);
guiPanel.add(passwordLabel, labelGBC);
guiPanel.add(passwordTextField, fieldGBC);
guiFrame.add(guiPanel, BorderLayout.NORTH);
guiFrame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new AuctionClient();
}
});
}
}
GridLayout, SpringLayout, GridBagLayout can do that by default
easiest coud be GridLayout(2, 2, 10, 10),
but every JComponents are resizable with its container
have to change horizontal alingment for JLabel (setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); or setHorizontalAlignment(JLabel.RIGHT);)
determine (JTextField TextFieldUserName = new JTextField(20)) initial Dimension for any of LayoutManager