How to remove JInternalFrame's Border? - java

I've searched about removing JInternalFrame's border, n I've got answer here. But now my query is after applying border to null, the border is not removed. As per second answer given in the question, I've tried to set border to Empty border n I've got success. And finally, my questions are as below.
Why border is not removed even if I set border to null (e.g. jif.setBorder(null);)?
I've set border to empty border (e.g. jif.setBorder(BorderFactory.createEmptyBorder());), but the titlebar of JInternalFrame is still visible, how to hide JInternalFrame's Title with its border?
Edited by Girish
My Code sample is as below:
package com.laxmiagencies.ui;
import java.awt.Color;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class MDIParent extends JFrame {
private static final long serialVersionUID = -7911142498378226657L;
public JDesktopPane jdp;
private JLabel apptitle;
private MDIListener listen;
public JMenuBar menubar;
private boolean islogin;
private boolean enablelogin;
private JMenuItem mnuabout;
public MDIParent()
{
super();
enablelogin=false;
init();
}
public MDIParent(String apptitle)
{
super(apptitle);
enablelogin=false;
init();
}
public MDIParent(String apptitle, boolean enablelogin)
{
super(apptitle);
this.enablelogin=enablelogin;
init();
}
public MDIParent(boolean enablelogin)
{
super();
this.enablelogin=enablelogin;
init();
}
public boolean isLoginEnabled()
{
return enablelogin;
}
public void setLoginEnabled(boolean enablelogin)
{
this.enablelogin=enablelogin;
this.islogin=!this.enablelogin;
}
public boolean isLoggedIn()
{
return islogin;
}
private void init()
{
listen=new MDIListener();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
jdp=new JDesktopPane();
jdp.setBounds(0, 0, getWidth(), getHeight());
jdp.addContainerListener(listen);
add(jdp);
setBounds(0, 0, Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height-50);
apptitle=new JLabel(getTitle());
apptitle.setBounds(20, 50, getWidth()-30, 70);
jdp.add(apptitle);
menubar=new JMenuBar();
mnuabout=new JMenuItem("About Us");
mnuabout.addActionListener(listen);
menubar.add(mnuabout);
setJMenuBar(menubar);
islogin=!enablelogin;
addComponentListener(listen);
}
public void setAppTitle(String apptitle)
{
setTitle(apptitle);
this.apptitle.setText(apptitle);
}
public void setTitleFont(Font font)
{
apptitle.setFont(font);
}
public void setTitleForeColor(Color color)
{
apptitle.setForeground(color);
}
//INFO Listener Class
private class MDIListener implements ComponentListener, ActionListener, ContainerListener
{
//INFO Used Methods
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==mnuabout)
{
AboutUs abt=new AboutUs();
jdp.add(abt);
abt.setVisible(true);
}
}
#Override
public void componentResized(ComponentEvent e)
{
jdp.setBounds(0, 0, getWidth(), getHeight());
for(JInternalFrame frame:jdp.getAllFrames())
{
frame.setSize(jdp.getWidth()-15, jdp.getHeight()-60);
}
}
#Override
public void componentShown(ComponentEvent e)
{
if(enablelogin)
{
if(!islogin)
{
setEnabled(false);
LoginWindow login=new LoginWindow();
login.setUndecorated(true);
login.setAlwaysOnTop(true);
login.setVisible(true);
}
}
}
#Override
public void componentAdded(ContainerEvent e)
{
if(e.getChild() instanceof JInternalFrame)
{
JInternalFrame child=(JInternalFrame)e.getChild();
child.setBounds(0, 0, jdp.getWidth()-15, jdp.getHeight()-60);
child.setBorder(javax.swing.BorderFactory.createEmptyBorder());
}
}
//INFO Unused methods
#Override
public void componentRemoved(ContainerEvent e){}
#Override
public void componentHidden(ComponentEvent e){}
#Override
public void componentMoved(ComponentEvent e){}
}
}
The JInternalFrame code is as follows
import javax.swing.BorderFactory;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
public class AboutUs extends JInternalFrame {
/**
*
*/
private static final long serialVersionUID = -4542063025572303166L;
private JPanel panel;
public AboutUs()
{
setTitle("About Us");
setLayout(null);
panel=new JPanel();
panel.setSize(200, 200);
panel.setBorder(BorderFactory.createTitledBorder("About Us"));
add(panel);
setMaximizable(true);
}
public JPanel getPanel()
{
return panel;
}
}
I've another question one:
3. How to disable of dragging JInternalFrame? i.e. the JInternalFrame must not be moved by user.

How to remove JInternalFrame's Border?
You use:
internalFrame.setBorder( null );
This works for me using JDK8 in Windows 7. If it doesn't work for you post a proper SSCCE.
how to hide JInternalFrame's Title with its border?
You can use the following. It will still leave a little border at the top if the internal frame to allow you to drag the frame around
internalFrame.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
If you don't need the dragging functionality then real question is why are you trying to remove the border? The point if using an internal frame is to allow the user to freely move the frame around the desktop by dragging the frame.
If all you need is a panel without a Border, then use a JPanel and add the panel to a parent panel. There is no need for the complexity of a JDestopPane/JInternalPane if you are not going to use those features.

Related

Why is JPanel still painted?

I am actually trying to create a JPanel, containing a bunch of ui elements for the user to manipulate the application. This panel is placed on top of Java3D scene. Therefore, I wanted the background of this JPanel to be transparent. Neither panel.setBackground(new Color(0,0,0,0)) nor popupPanel.setOpaque(false) nor both calls made the panel background transparent. So I decided to sub-class JPanel and play with paintComponent. No effect. Then I tried paint. Nothing. Then I got confused. So I overwrote literally every method I know of, related to painting a JPanel and left each method body blanc (see below). When I run the application, I still get the panel. How can that be? I placed some System.out.println to be sure that the class is the right one, and is called. It is the right one. Despite all this missing code, the only difference to a normal JPanel is that the button is only painted if the mouse enters the button bounds. What am I missing?
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JPanel;
public class TransparentPanel extends JPanel {
protected Color bg = new Color(0,0,0,0);
public TransparentPanel() {
super();
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) { }
#Override
public void paint(Graphics g) {
System.out.println(System.getProperty("java.vendor"));
System.out.println(System.getProperty("java.version"));
for(Component c: getComponents()) {
System.out.println(c.toString());
}
}
#Override
public void repaint(Rectangle r) {}
#Override
public void repaint(long tm,int x,int y,int width, int height) {}
#Override
protected void paintChildren(Graphics g) {}
#Override
protected void paintBorder(Graphics g) {}
#Override
public void paintImmediately(int x,int y,int width, int height) {}
#Override
public void paintImmediately(Rectangle r) {}
}
and
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
public class OverlayoutTest extends JFrame {
public OverlayoutTest() {
super("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(400, 300));
add(createPanel());
setLocationRelativeTo(null);
setVisible(true);
}
private JPanel createPanel() {
JPanel mainPanel = new JPanel(){
#Override
public boolean isOptimizedDrawingEnabled() {
return false;
}
};
mainPanel.setLayout(new OverlayLayout(mainPanel));
JComponent popupPanel = createPopupPanel();
popupPanel.setAlignmentX(1.0f);
popupPanel.setAlignmentY(0.0f);
mainPanel.add(popupPanel);
SpatialView view = new SpatialView(null); // A class extending JPanel containing a Java3D Canvas3D in a BorderLayout
mainPanel.add(view);
view.addScaledPlanetModel();
return mainPanel;
}
private JComponent createPopupPanel() {
TransparentPanel popupPanel = new TransparentPanel();
// popupPanel.setBackground(new Color(0,0,0,0));
// popupPanel.setOpaque(false);
popupPanel.setMaximumSize(new Dimension(250, 300));
JButton button = new JButton("HI there!"); // the button does nothing but is nice to spot
button.setForeground(Color.WHITE);
popupPanel.add(button );
return popupPanel;
}
public static void main(String[] args) {
new OverlayoutTest();
}
}
I am using OpenJDK version "11" 2018-09-25, build 11+28 and Java3D 1.7.0

How to use a JPanel as JButton?

I must use a swing-ui designer tool to create my UI, that only supports graphically editing JPanels. Those panels (they basically contain complex button designs) to work like a JButton. I cannot use anything other than JPanel as base class of these panels (UI editor limitation).
What is the most generic solution to do this?
Create a custom button that uses the panel's draw method instead of
it's own?
Create a base-panel class that reimplements the whole
button?
Another more elegant solution?
Here is a quick demo, to show you how you could use borders to simulate a button.
The demo also reacts to mouse and key events :
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
public class JPanelButton extends JPanel {
Border raisedetched = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
Border loweredetched = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
public static void main(final String[] args) {
JFrame frame = new JFrame();
final JPanelButton panel = new JPanelButton();
panel.raiseBorder();
panel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(final MouseEvent e) {
panel.lowerBorder();
}
#Override
public void mouseReleased(final MouseEvent e) {
panel.raiseBorder();
}
});
panel.setFocusable(true); // you need this or the panel won't get the key events
panel.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(final KeyEvent e) {
panel.lowerBorder();
}
#Override
public void keyReleased(final KeyEvent e) {
panel.raiseBorder();
}
});
frame.setContentPane(panel);
frame.setSize(100, 100);
frame.setVisible(true);
}
public void raiseBorder() {
setBorder(raisedetched);
}
public void lowerBorder() {
setBorder(loweredetched);
}
}
Simply add MouseListener.
JPanel jp = new JPanel();
jp.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
System.out.println("Clicked");
}
});
If this answer isn't specific enough, leave a comment and I'll give you more explanation.

JFrame - Manual Resizing Issue

Good evening,
I created a window with a costum layout and a JPanel. When I resize it manually, it flickers because Java draws the JPanel false to draw it a second time at the right position.
I made a short example-program including my problem:
public class Starter {
private static TestWindow testWindow;
public static void main(String[] args) {
testWindow = new TestWindow();
}
}
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestWindow {
private JFrame frame;
public TestWindow() {
frame = new JFrame();
frame.setBounds(100, 100, 765, 599);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLayout(new OwnLayout());
JPanel pnl = new JPanel();
pnl.setBackground(Color.BLUE);
frame.add("", pnl);
}
}
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import javax.swing.JPanel;
public class OwnLayout implements LayoutManager {
JPanel pnl;
public OwnLayout() {
}
#Override
public void addLayoutComponent(String name, Component comp) {
pnl = (JPanel) comp;
}
#Override
public void layoutContainer(Container parent) {
if (pnl != null)
pnl.setBounds((int) parent.getWidth() - 50, 0, 50, (int) parent.getHeight());
}
#Override
public Dimension minimumLayoutSize(Container parent) {
return null;
}
#Override
public Dimension preferredLayoutSize(Container parent) {
return null;
}
#Override
public void removeLayoutComponent(Component comp) {
pnl = null;
}
}
The flickering only appears, when dragging the left border of the frame.
The issue may link to:
Due to the asynchronous nature of native event handling, the results
returned by getBounds, getLocation, getLocationOnScreen, and getSize
might not reflect the actual geometry of the Window on screen until
the last request has been processed. During the processing of
subsequent requests these values might change accordingly while the
window management system fulfills the requests.
(quoted from https://docs.oracle.com/javase/7/docs/api/java/awt/Window.html)
I need a solution to prevent the flickering. Does anyone have an idea?

Making a JTextField with Vanishing Text

I am familiar that you can input text before hand into a JTextField. This text will be displayed in the JTextField and has to be manually deleted when having to input your own text into the JTextField. For example, consider this JTextField:
cruiseSel = new JTextField ("Selected Cruise:");
cruiseSel.setEditable(false);
centerP12.add(cruiseSel);
contentPane12.add(centerP12, BorderLayout.CENTER);
Frame12.setVisible(true);
Upon running the above, a JTextField will appear with "Selected Cruise:" written within it. This text then has to be manually deleted to clear the text field.
Is there a way to input text in an JTextField, so once the GUI opens, the text will be displayed, but when the JTextField is selected to input manual text, the text vanishes?
You could use a FocusListener and when the JTextField receives focus, empty the text.
Of course you will want a state marker to indicate it has the default text and not do this once you have user entered text. Either that or after the FocusListener is hit the first time, remove it.
textField.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
JTextField source = (JTextField)e.getComponent();
source.setText("");
source.removeFocusListener(this);
}
});
What you are looking for is called placeholder. I've written this class a while ago:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
/**
* #author xehpuk
*/
public class PlaceholderTextField extends JTextField {
private static final long serialVersionUID = -5529071085971698388L;
/**
* The placeholder to be displayed if the text field is empty.
*/
private String placeholder;
/**
* Determines whether the placeholder should be displayed even on focus.
*/
private boolean paintingOnFocus;
/**
* The color the placeholder should be displayed in.
*/
private Color placeholderColor;
public String getPlaceholder() {
return placeholder;
}
public void setPlaceholder(final String placeholder) {
this.placeholder = placeholder;
repaint();
}
public boolean isPaintingOnFocus() {
return paintingOnFocus;
}
public void setPaintingOnFocus(final boolean paintingOnFocus) {
this.paintingOnFocus = paintingOnFocus;
repaint();
}
public Color getPlaceholderColor() {
return placeholderColor;
}
public void setPlaceholderColor(final Color placeholderColor) {
this.placeholderColor = placeholderColor;
repaint();
}
public PlaceholderTextField() {
super();
}
public PlaceholderTextField(final Document doc, final String text, final int columns) {
super(doc, text, columns);
}
public PlaceholderTextField(final int columns) {
super(columns);
}
public PlaceholderTextField(final String text, final int columns) {
super(text, columns);
}
public PlaceholderTextField(final String text) {
super(text);
}
{
addFocusListener(new RepaintFocusListener());
}
#Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
if (getPlaceholder() != null && getText().isEmpty() && (isPaintingOnFocus() || !isFocusOwner())) {
try {
final Rectangle rect = getUI().modelToView(this, 0);
final Insets insets = getInsets();
g.setFont(getFont());
g.setColor(getPlaceholderColor() == null ? getForeground() : getPlaceholderColor());
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString(getPlaceholder(), rect.x, getHeight() - insets.top - insets.bottom - rect.y);
} catch (final BadLocationException e) {
throw new RuntimeException(e);
}
}
}
private class RepaintFocusListener implements FocusListener {
#Override
public void focusGained(final FocusEvent e) {
repaint();
}
#Override
public void focusLost(final FocusEvent e) {
repaint();
}
}
}
You can choose the text and the color and whether it should be painted even if the text field has focus.
The crucial part is the overriding of paintComponent(Graphics).
You can use SwingX Read on this How to set Text like Placeholder in JTextfield in swing
I include the sample code here for your use
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.jdesktop.swingx.prompt.PromptSupport;
public class PromptExample {
public static void main(String[] args) {
new PromptExample();
}
public PromptExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField bunnies = new JTextField(10);
JTextField ponnies = new JTextField(10);
JTextField unicorns = new JTextField(10);
JTextField fairies = new JTextField(10);
PromptSupport.setPrompt("Bunnies", bunnies);
PromptSupport.setPrompt("Ponnies", ponnies);
PromptSupport.setPrompt("Unicorns", unicorns);
PromptSupport.setPrompt("Fairies", fairies);
PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, bunnies);
PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIGHLIGHT_PROMPT, ponnies);
PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.SHOW_PROMPT, unicorns);
PromptSupport.setFontStyle(Font.BOLD, bunnies);
PromptSupport.setFontStyle(Font.ITALIC, ponnies);
PromptSupport.setFontStyle(Font.ITALIC | Font.BOLD, unicorns);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(bunnies, gbc);
frame.add(ponnies, gbc);
frame.add(unicorns, gbc);
frame.add(fairies, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Check out Text Prompt.
It supports this functionality along with a couple of features to customize the behaviour of the prompt.
To achieve something like this, you would generally need to create a certain type of event listener. In your case, the desired action needs to be triggered on a mouse event - thus the MouseAdapter event listener seems like a good fit (at first glance). To use the MouseAdapter
abstract class, you'd need to extend it and override the necessary methods (see here for a full list of available methods).
The shortest way of achieving this is via an anonymous class declaration, like so:
cruiseSel.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
cruiseSel.setText("");
}
});
(However, if you need to override multiple methods or the triggered logic feels complex enough, you might be better off creating a separate listener class.)
EDIT: Alternatively, as #HovercraftFullOfEels pointed out in the comment section, it would probably be wiser to apply the FocusAdapter class (see here) in an identical fashion:
cruiseSel.addFocusListener(new FocusAdapter(){
#Override
public void focusGained(FocusEvent e){
cruiseSel.setText("");
}
});
The problem with the first solution is that it is only concerned with listening for actual MOUSE CLICKS on the text field, while the latter listens for ANY types of focus-gains on it. Thus, when using the TAB key to switch between text fields, only the second solution would perform correctly.

JLabel mouse click on icon or text

When it is clicked on JLabel, I want to understand if the click was on "Icon part", or "Text part" of the JLabel, so that different action can be taken. Is there a clever way to do that? Or just I have to solve it relatively with the coordinates of the icon and text?
+1 to #aymeric comment.
What about having two different JLabels
However I do understand why you might be hesitating
negative: requires maintenance of 2 labels.
My clever (:P) solution to this is create your own abstract component - which accepts icon and text as parameters for constructor - by extending JPanel and than adding 2 JLabels to the JPanel, each label has its on MouseAdapter which calls abstract method xxxClicked() (thus any implementing class must override these methods).
Here is an example I made:
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon ii = null;
try {
//I dont remmend getScaledInstance just used it for speed of code writing
ii = new ImageIcon(ImageIO.read(new URL("http://www.candonetworking.com/java.gif")).getScaledInstance(32, 32, Image.SCALE_SMOOTH));
} catch (Exception ex) {
ex.printStackTrace();
}
MyLabel ml = new MyLabel(ii, "Something") {
#Override
void iconClicked() {
System.out.println("Icon clicked");
}
#Override
void textClicked() {
System.out.println("Text clicked");
}
};
frame.add(ml);
frame.pack();
frame.setVisible(true);
}
});
}
}
abstract class MyLabel extends JPanel {
JLabel iconLabel;
JLabel textLabel;
MouseAdapter iconMA;
MouseAdapter textMA;
public MyLabel(ImageIcon icon, String text) {
iconLabel = new JLabel(icon);
textLabel = new JLabel(text);
iconMA = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
iconClicked();
}
};
textMA = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
textClicked();
}
};
iconLabel.addMouseListener(iconMA);
textLabel.addMouseListener(textMA);
add(iconLabel);
add(textLabel);
}
abstract void iconClicked();
abstract void textClicked();
public JLabel getIconLabel() {
return iconLabel;
}
public JLabel getTextLabel() {
return textLabel;
}
}

Categories

Resources