I need to add a JLabel/JPanel as shown in the image. When resizing the frame both the tabbed pane and the Label/panel should be resided. The label and the panel inside the Tabbed Pane are independent. How can I do that?
Here is a quick example to use JLayer(as suggested by mKorbel):
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class TopRightCornerLabelLayerUITest {
public static JComponent makeUI() {
JTabbedPane tab = new JTabbedPane();
tab.addTab("New tab1", new JLabel("1"));
tab.addTab("New Tab2", new JLabel("2"));
JPanel p = new JPanel(new BorderLayout());
p.add(new JLayer<JComponent>(tab, new TopRightCornerLabelLayerUI()));
return p;
}
private static void createAndShowUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowUI();
}
});
}
}
class TopRightCornerLabelLayerUI extends LayerUI<JComponent> {
private JLabel l = new JLabel("A Label at right corner");
private JPanel rubberStamp = new JPanel();
#Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
Dimension d = l.getPreferredSize();
int x = c.getWidth() - d.width - 5;
SwingUtilities.paintComponent(g, l, rubberStamp, x, 2, d.width, d.height);
}
}
I need to add a JLabel/JPanel as shown in the image. When resizing the
frame both the tabbed pane and the Label/panel should be resided. The
label and the panel inside the Tabbed Pane are independent.. If any
one have the solution, please help me.
You can use:
JLayer (Java7) based on JXLayer(Java6)
GlassPane, for example
I'd use JLayer if is possible (requires Java7).
Related
For a programming class, I was asked to create a replica of an iCalendar app. I'm using JAVA to code it, and JFrame and JPanel to draw it. Here is a SSCCEE of my problem:
import java.awt.*;
import javax.swing.*;
public class Mainie extends JFrame {
private JButton back = new TriangleButton(true),
front = new TriangleButton(false);
public Mainie(){
super();
setSize(800, 400);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel months = new JPanel();
final JPanel days = new JPanel();
JLabel one = new JLabel("Hallo");
one.setHorizontalAlignment(JLabel.CENTER);
back.setHorizontalAlignment(SwingConstants.LEFT);
front.setHorizontalAlignment(SwingConstants.RIGHT);
months.setLayout(new BorderLayout());
months.add(back, BorderLayout.WEST);
months.add(one, BorderLayout.CENTER);
months.add(front, BorderLayout.EAST);
days.setLayout(new GridLayout(1,1));
days.add(new JButton("Meister Camickr"));
months.setAlignmentX(CENTER_ALIGNMENT);
add(months, BorderLayout.NORTH);
add(days, BorderLayout.CENTER);
setVisible(true);
}
public static void main(String[] args){
new Mainie();
}
}
class TriangleButton extends JButton {
private Shape triangle = createTriangle();
public void paintBorder(Graphics g) {
((Graphics2D) g).draw(triangle);
}
public void paintComponent(Graphics g) {
((Graphics2D) g).fill(triangle);
}
public Dimension getPreferredSize() {
return new Dimension(200, 100);
}
public boolean contains(int x, int y) {
return triangle.contains(x, y);
}
public TriangleButton(boolean pointLeft) {
super();
if (!pointLeft)
this.triangle = createRTriangle();
}
private Shape createTriangle() {
Polygon p = new Polygon();
p.addPoint(0, 20);
p.addPoint(20, 0);
p.addPoint(20, 40);
return p;
}
private Shape createRTriangle() {
Polygon p = new Polygon();
p.addPoint(20, 20);
p.addPoint(0, 0);
p.addPoint(0, 40);
return p;
}
}
If you compile this, you can see that my JButton is too far to the left. How can I move it to the right?
The basic problem with those buttons is that the button is very wide and the visual indicator is to the left. Put a border around them and it becomes obvious.
OTOH I would use an entirely different approach, using text for the buttons and a factory method to make them look as expected.
import java.awt.*;
import javax.swing.*;
public class CustomPointerButtons {
JPanel ui;
CustomPointerButtons() {
initUI();
}
private final void initUI() {
ui = new JPanel(new BorderLayout(4, 4));
JPanel topPanel = new JPanel(new BorderLayout(4, 4));
ui.add(topPanel, BorderLayout.PAGE_START);
ui.add(new JButton("Mister Mix")); //will default to CENTER
topPanel.add(new JLabel("Blah, Blah.."));
JButton back = getMinimalButton(new String(Character.toChars(9668)));
topPanel.add(back, BorderLayout.LINE_START);
JButton forward = getMinimalButton(new String(Character.toChars(9658)));
topPanel.add(forward, BorderLayout.LINE_END);
}
public JButton getMinimalButton(String text) {
JButton b = new JButton(text);
b.setFont(b.getFont().deriveFont(40f));
b.setMargin(new Insets(0,0,0,0));
b.setContentAreaFilled(false);
b.setBorder(null);
return b;
}
public final JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("Custom Pointer Buttons");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setContentPane(new CustomPointerButtons().getUI());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
The problem is your random preferred size doesn't represent the real size of the triangle.
You can do something like:
public Dimension getPreferredSize() {
//return new Dimension(200, 100);
Rectangle bounds = triangle.getBounds();
return new Dimension(bounds.width, bounds.height);
}
You still have other problems because you will still have painting artifacts. You should always invoke super.paintComponent() when you override the method:
public void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).fill(triangle);
}
However, this still doesn't really work because the button does other painting as well. So the real problem is that you should not be trying to do custom painting of the button. What you really want to do is custom painting of an Icon. Then you can just add the Icon to the button.
You may want to check out Playing With Shapes. You can use the ShapeIcon class to create your icons. This will provide a more flexible solution since I'm guess all shapes are not represented by an ascii character.
I have 2 JPanel, named as "panelMenu" and "panelTable". Both of them are added into JDesktopPane, named as "desktop". I have put a button in "panelMenu" and when it is clicked, it will bring up a JInternalFrame.
Both of the panels are set side by side in the "desktop"...here comes the problem...when I clicked on the button...the JInternalFrame will show up but it is initially at the back of the "panelTable"...how can I bring the JInternalFrame to be always on top of any other components?
//Adding panels into desktop
panelMenu.setBackground(Color.yellow);
panelMenu.setBounds(0,0,200,800);
panelMenu.setLayout(null);
panelTable.setBackground(Color.gray);
panelTable.setBounds(250,50,700,700);
panelTable.setLayout(null);
desktop.setLayout(null);
desktop.setSize(width, height);
desktop.setBackground(Color.gray);
desktop.add(panelMenu);
desktop.add(panelTable);
this.add(desktop);
How about using JOptionPane.showInternalXXXDialog(...):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class InternalMessageDialogTest {
private final JDesktopPane desktop = new JDesktopPane();
public JComponent makeUI() {
JButton button = new JButton(new AbstractAction("open") {
#Override public void actionPerformed(ActionEvent e) {
JOptionPane.showInternalMessageDialog(
desktop, "information", "modal",
JOptionPane.INFORMATION_MESSAGE);
}
});
JPanel panelMenu = new JPanel();
panelMenu.setBackground(Color.YELLOW);
panelMenu.add(button);
panelMenu.setBounds(0, 0, 100, 100);
JInternalFrame panelTable = new JInternalFrame("Table");
panelTable.add(new JScrollPane(new JTable(30, 3)));
panelTable.setBounds(100, 0, 200, 100);
desktop.add(panelMenu);
desktop.add(panelTable);
panelMenu.setVisible(true);
panelTable.setVisible(true);
JPanel p = new JPanel(new BorderLayout());
p.add(desktop);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new InternalMessageDialogTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
Following code will help you
//yourDesktopPane
//panelMenu
//panelTable
//buttonMenu
//buttonTable
private void buttonMenuMouseClicked(java.awt.event.MouseEvent evt) {
panelMenu obj = new panelMenu ();
BasicInternalFrameUI bi = (BasicInternalFrameUI) obj.getUI();
bi.setNorthPane(null);
obj.setBounds(0, 0, 1220, 700);//your desired values
obj.setVisible(true);
yourDesktopPane.add(obj);
obj.toFront();
}
private void buttonTableMouseClicked(java.awt.event.MouseEvent evt) {
panelTableobj = new panelTable();
BasicInternalFrameUI bi = (BasicInternalFrameUI) obj.getUI();
bi.setNorthPane(null);
obj.setBounds(0, 0, 1220, 700);//your desired values
obj.setVisible(true);
yourDesktopPane.add(obj);
obj.toFront();
}
I'm trying to set the height of a JTextField. At present its the full size of the displayed JFrame. Any ideas how I set the height to 50?
Edit: Here is the amended code along with screenshot thanks!
public class Display extends JFrame {
private DrawCanvas canvas;
private JTextField Altitude;
private JTextField TASpeed;
private JLabel altButton;
private int countA = 0;
private int countS = 0;
private int Bcount1 = 0;
public String Ccount = Integer.toString(Bcount1);
public Display() {
canvas = new DrawCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
canvas.setLayout(new BorderLayout());
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(canvas, BorderLayout.LINE_START);
//here are the 2 side fields![enter image description here][2]
Altitude = new JTextField("0", 5);
Altitude.setHorizontalAlignment(JTextField.CENTER);
Altitude.setEditable(false);
Altitude.setOpaque(false);
Altitude.setFont(Altitude.getFont().deriveFont(25f));
TASpeed = new JTextField("0", 5);
TASpeed.setHorizontalAlignment(JTextField.CENTER);
TASpeed.setEditable(false);
TASpeed.setOpaque(false);
TASpeed.setFont(Altitude.getFont().deriveFont(25f));
altButton = new JLabel();
altButton.setText(Ccount);
canvas.add(altButton, BorderLayout.SOUTH);
canvas.add(Altitude, BorderLayout.LINE_END);
canvas.add(TASpeed, BorderLayout.LINE_START);
canvas.add(new JLabel(Ccount), BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("FLIGHT DISPLAY");
pack();
setVisible(true);
requestFocus();
}
class DrawCanvas extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(CANVAS_BACKGROUND);
g.setColor(GROUND_COLOR);
g.drawString(Ccount, 100, 100);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Display();
}
});
}
}
As #kleopatra correctly comments, the JTextField can calculate it's own preferred size based on the platform designer's choice of Font. This example changes the size.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/** #see http://stackoverflow.com/a/14734937/230513 */
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField tfCount = new JTextField("42", 8);
tfCount.setHorizontalAlignment(JTextField.CENTER);
tfCount.setFont(tfCount.getFont().deriveFont(50f));
f.add(tfCount, BorderLayout.NORTH);
f.add(new JPanel() { //placeholder
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}, BorderLayout.CENTER);
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();
}
});
}
}
I'd like to custom a little bit the basic JSpinner of swing java API.
Basically, I want to move the textfield component initially located on the left of the arrow buttons. Instead, the texfield would be lcoated between the two arrows of the spinner, so that there's one arrow on top of the textfield and one arrow below the texfield.
But I don't know how to proceed...
Anyone would have an idea?
You might be able to override the setLayout(LayoutManager) method of JSpinner to use a custom LayoutManager.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SpinnerLayoutTest {
public JComponent makeUI() {
SpinnerNumberModel m = new SpinnerNumberModel(10, 0, 1000, 1);
JSpinner spinner = new JSpinner(m) {
#Override public void setLayout(LayoutManager mgr) {
super.setLayout(new SpinnerLayout());
}
};
JPanel p = new JPanel(new BorderLayout(5,5));
p.add(new JSpinner(m), BorderLayout.NORTH);
p.add(spinner, BorderLayout.SOUTH);
p.setBorder(BorderFactory.createEmptyBorder(16,16,16,16));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SpinnerLayoutTest().makeUI());
f.setSize(320, 160);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class SpinnerLayout extends BorderLayout {
#Override public void addLayoutComponent(Component comp, Object constraints) {
if("Editor".equals(constraints)) {
constraints = "Center";
} else if("Next".equals(constraints)) {
constraints = "North";
} else if("Previous".equals(constraints)) {
constraints = "South";
}
super.addLayoutComponent(comp, constraints);
}
}
You could make an JPanel and put a JTextField and the JButtons inside it. That's was soulution, when I had the same problem.
EDIT:
Arrowbuttons can you create with:
new javax.swing.plaf.basic.BasicArrowButton(SwingConstants.NORTH);
Where SwingConstants.NORTH says that the arrow in the button is pointing upwards
I have created a divider in JSplitPane. I am unable to set the color of divider. I want to set the color of divider. Please help me how to set color of that divider.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SplitPaneDemo {
JFrame frame;
JPanel left, right;
JSplitPane pane;
int lastDividerLocation = -1;
public static void main(String[] args) {
SplitPaneDemo demo = new SplitPaneDemo();
demo.makeFrame();
demo.frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
demo.frame.show();
}
public JFrame makeFrame() {
frame = new JFrame();
// Create a horizontal split pane.
pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
left = new JPanel();
left.setBackground(Color.red);
pane.setLeftComponent(left);
right = new JPanel();
right.setBackground(Color.green);
pane.setRightComponent(right);
JButton showleft = new JButton("Left");
showleft.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(left, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showright = new JButton("Right");
showright.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(right, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showboth = new JButton("Both");
showboth.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
c.remove(pane);
c.remove(left);
c.remove(right);
pane.setLeftComponent(left);
pane.setRightComponent(right);
c.add(pane, BorderLayout.CENTER);
if (lastDividerLocation >= 0) {
pane.setDividerLocation(lastDividerLocation);
}
c.validate();
c.repaint();
}
});
JPanel buttons = new JPanel();
buttons.setLayout(new GridBagLayout());
buttons.add(showleft);
buttons.add(showright);
buttons.add(showboth);
frame.getContentPane().add(buttons, BorderLayout.NORTH);
pane.setPreferredSize(new Dimension(400, 300));
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.pack();
pane.setDividerLocation(0.5);
return frame;
}
}
Thanks
Sunil kumar Sahoo
Or, since the divider is a container, you can do the following:
dividerContainer = (BasicSplitPaneDivider) splitPane.getComponent(2);
Component leftBtn = dividerContainer.getComponent(0);
Component rightBtn = dividerContainer.getComponent(1);
dividerContainer.setBackground(Color.white);
dividerContainer.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
dividerContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
dividerContainer.add(toolbar);
dividerContainer.setDividerSize(toolbar.getPreferredSize().height);
This code works for me:
splitPane.setUI(new BasicSplitPaneUI() {
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
public void setBorder(Border b) {
}
#Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, getSize().width, getSize().height);
super.paint(g);
}
};
}
});
splitPane.setBorder(null);
You can change divider color "g.setColor(new Color(R,G,B))".
This worked for me fine.First you are creating JFrame with it's normal methods such as setDefaultCloseOperation(), setBounds(), getContentPane(). Then create an object from your class then use that to call all the other methods through out the program, in this case I created object called app. One thing you have to keep in mind is that don't forget to use ActionListener e.
Also color changes must go with setBackground() function, while you getting the values from getSource() for the color change.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Main implements ActionListener {
private static void createAndShowGUI() {
Main app=new Main();
// make frame..
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("I am a JFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20,30,300,120);
frame.setLayout(null);
//Create a split pane
JSplitPane myPane = new JSplitPane();
myPane.setOpaque(true);
myPane.setDividerLocation(150);
app.right = new JPanel();
app.right.setBackground(new Color(255,0,0));
app.left = new JPanel();
app.left.setBackground(new Color(0,255,0));
app.left.setLayout(null);
myPane.setRightComponent(app.right);
myPane.setLeftComponent(app.left);
// make buttons
app.butt1=new JButton("Red");
app.butt2=new JButton("Blue");
app.butt3=new JButton("Green");
// add and size buttons
app.left.add(app.butt1);
app.butt1.setBounds(10,10, 100,20);
app.left.add(app.butt2);
app.butt2.setBounds(10,30, 100,20);
app.left.add(app.butt3);
app.butt3.setBounds(10,50, 100,20);
// set up listener
app.butt1.addActionListener(app);
app.butt2.addActionListener(app);
app.butt3.addActionListener(app);
frame.setContentPane(myPane);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
// check which button and act accordingly
if (e.getSource()==butt1)
right.setBackground(new Color(255,0,0));
if (e.getSource()==butt2)
right.setBackground(new Color(0,0,255));
if (e.getSource()==butt3)
right.setBackground(new Color(0,255,0));
}
public static void main(String[] args) {
// start off..
try {
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel" );
}
catch (Exception e)
{
System.out.println("Cant get laf");
}
Object a[]= UIManager.getInstalledLookAndFeels();
for (int i=0; i<a.length; i++)
System.out.println(a[i]);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
// application object fields
int clickCount=0;
JLabel label;
JButton butt1;
JButton butt2;
JButton butt3;
JPanel left;
JPanel right;
}