JLabel tooltip is not visible on top of BrowserView - java

I have this problem: tooltip of the label (JLabel) is hidden by a BrowserView.
The tooltip properly shown top of any other java component, but gets hidden by BrowserView. What I want is to make the tooltip visible on top of BrowserView. Anyone knows the reason for it and a way to get the tooltip visible.
Resulted UI and how tooltip is hidden is attached here.
Code sample:
public class TestFrame
{
public static void main (String args[])
{
JSplitPane splitPane = new JSplitPane();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel topPanel = new JPanel();
topPanel.setBorder(new LineBorder(Color.black));
topPanel.setSize(75, 75);
JLabel label = new JLabel("TestLabel");
label.setToolTipText("Test Tooltip 1");
topPanel.add(label);
splitPane.setLeftComponent(topPanel);
Browser browser = new Browser();
BrowserView browserView = new BrowserView(browser);
splitPane.setRightComponent(browserView);
browser.loadURL("http://www.google.com");
frame.add(splitPane);
frame.setSize(700, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Result UI: Right panel is a BrowserView which hides the Tooltip of left panel label

To let all know, the reason for this is JXBrowser is of 1.6.17 and it comes as Heavyweight by default.
And the Jtooltip is LightWeight. because of that Jtooltip is does not appear on top of the Heavyweight browser.
Few solutions.
1. Make the Browser lightweight (com.teamdev.jxbrowser.chromium.BrowserType#LIGHTWEIGHT)
2. Make the Tooltip HeavyWeight

You can override getToolTipLocation() and set tooltip text at a particular location (define x and y coordinates):
class BrowserLabel extends JLabel {
public BrowserLabel(String text) {
setText(text);
}
#Override
public Point getToolTipLocation(MouseEvent e) {
return new Point(x, y);
}
}

Related

Java basic GUI blank

When I run this program it appears as an empty window until you fullscreen, then it can be resized as you like, why is it doing this/how do I stop it?
the program is very basic just a menubar and two panels split.
public class SplitPane {
public static void main(String[] args) {
window view = new window();
}
private static class window extends JFrame {
public window() {
this.setSize(1000, 750);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//menubar is here, must lower code quantity for stack
//panels
//graph half
JPanel graphRep = new JPanel();
//Background colour - graphRep.setBackground(Color.RED);
graphRep.setVisible(true);
String graphTitle = "Textual Representation.";
Border graphBorder = BorderFactory.createTitledBorder(graphTitle);
graphRep.setBorder(graphBorder);
//text half
JPanel textRep = new JPanel();
textRep.setVisible(true);
String textTitle = "Graphical Representation.";
Border textBorder = BorderFactory.createTitledBorder(textTitle);
textRep.setBorder(textBorder);
//splitpane
JSplitPane splitPane = new JSplitPane();
splitPane.setSize(600, 750);
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerSize(10);
splitPane.setDividerLocation(250);
splitPane.setLeftComponent(graphRep);
splitPane.setRightComponent(textRep);
this.add(splitPane);
}
}
this.setVisible(true);
You are making the frame visible BEFORE you add components to the frame. The layout manager is never invoked so the size of all the components remains (0, 0) so there is nothing to paint.
The frame should be made visible AFTER all the components have been added to the frame.
And the code should be:
frame.pack();
frame.setVisible();
So each component is displayed at its proper size. Don't hardcode the size() because you don't know what the size of a users screen might be.

JTextField showing through JComboBox's dropdown after Scrolling

When a JTextField is in a JScrollPanel, if the panel has been scrolled, whenever the dropdown from a JComboBox is over the JTextField, the text field shows through the dropdown.
This only happens after the content has been scrolled (not on startup of the application).
The main question is how can we fix this?
Bonus points if the answer:
Is not a hack
Explains why is it happening in the first place
Things I've tried:
Moving the dropdown outside of the scrollpane (no change)
Adding a repaint to any and every container I could find on scroll (no change)
Different Layout managers for the content of the scrollpane (no change)
Code Example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TextFieldShowsThrough{
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createScrollDemo());
frame.pack();
// For demonstration purposes
frame.setSize(frame.getWidth() + 100, frame.getHeight() - 100);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static JScrollPane createScrollDemo(){
final Box optionsPanel = Box.createVerticalBox();
optionsPanel.add(createDropDown());
optionsPanel.add(createTextField("Option1"));
optionsPanel.add(createTextField("Option2"));
optionsPanel.add(createTextField("Option3"));
optionsPanel.add(createTextField("Option4"));
optionsPanel.add(createTextField("Option5"));
optionsPanel.add(Box.createVerticalGlue());
JScrollPane result = new JScrollPane(optionsPanel);
// Made attempts to fix here, but to no avail
/*result.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
#Override
public void adjustmentValueChanged(AdjustmentEvent e) {
result.repaint();
}
});*/
return result;
}
public static Box createDropDown(){
Box b = Box.createVerticalBox();
b.setAlignmentX(JLabel.LEFT_ALIGNMENT);
b.add(new JLabel("Language"));
JComboBox combo = new JComboBox(new String[]{"en", "fr", "es"});
combo.setMaximumSize(new Dimension(500, 25));
b.add(combo);
return b;
}
public static Box createTextField(String label){
Box mainBox = Box.createVerticalBox();
mainBox.setOpaque(true);
mainBox.setBackground(new Color((int)(Math.random() * 0x1000000))); // because fun
JLabel jLabel = new JLabel(label);
jLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
mainBox.add(jLabel);
Box secondaryBox = Box.createHorizontalBox();
secondaryBox.setAlignmentX(JLabel.LEFT_ALIGNMENT);
TextField tf = new TextField();
tf.setMaximumSize(new Dimension(500, 25));
secondaryBox.add(tf);
mainBox.add(secondaryBox);
return mainBox;
}
}
That's because you're using a java.awt.TextField, which is heavy weight component, inside a light weight container. The popup window used by the JComboBox can also be a light weight component.
AWT components don't play well with Swing components, they have z-ordering issues.
Change TextField tf = new TextField(); to JTextField tf = new JTextField();
You should also avoid using setPreferred/Minimum/MaximumSize (see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more details) and instead use layout constraints and sizing hints (like the columns property of the JTextField)

JDialog box with JtextField ..NO NEED TO CLICK to start typing .!

I want to create a JDialog which has a JTextField, this dialog box should start taking input from user no sooner it starts(i.e WITHOUT user having to click on it). I am calling the code using combination of key tap.So if any other app is running and I would want to pop this dialog box, i would just press the required keys.However currently, I have to click on the dialog box when it pops beacuse the present running app has the focus.Anyhelp..Thanks
//Creating a panel
JPanel panel = new JPanel( new SpringLayout() );
//creating a text field
final JTextField textfield = new JTextField(65);
// Modifying text field
Font font = new Font("SansSerif",Font.LAYOUT_LEFT_TO_RIGHT, 19);
textfield.setFont(font);
textfield.setForeground(Color.black);
textfield.setBackground(new Color(200,200,200,70)); //253,245,230
//border
textfield.setBorder(new BevelBorder(BevelBorder.LOWERED));
textfield.requestFocusInWindow();
//modifying panel
label.setLabelFor(textfield);
panel.add(textfield);
panel.setBackground(new Color(0,0,0,25));
panel.setPreferredSize(new Dimension(750,70));
panel.setBorder(new EtchedBorder(EtchedBorder.RAISED));
//Lay out the panel.
SpringUtilities.makeCompactGrid(panel,
1 , 2, //rows, cols
10, 10, //initX, initY
10, 10); //xPad, yPad
//Create and set up the Window Frame
final JDialog frame = new JDialog();
frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
//Positioning the dialog at the center of screen
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/4-frame.getSize().width/4, dim.height/3-frame.getSize().height/3);
//Set up the content pane.
//adding background
frame.setLayout(new SpringLayout());
frame.setUndecorated(true);
frame.add(panel);
frame.setSize(750,71);
frame.repaint();
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
frame.toFront();
frame.setAlwaysOnTop(true);
frame.repaint();
frame.setVisible(true);
}
});
frame.addWindowFocusListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
frame.requestFocus();
}
});
Almost every line of code is not needed or in the wrong order:
frame.pack();
frame.setSize(750,71);
Well, make up your mind what are you trying to do? The pack() method is used to have the frame automatically calculate the size based on the components added to the frame. The setSize() would override the results of the pack() method. You should only pack() the frame AFTER adding all the components to the frame.
frame.repaint();
No need for the repaint(), the setVisible(true) method will make sure the frame is painted.
frame.requestFocus();
Not needed, when the frame is made visible focus will automatically go to the first component.
So the basic order of your code should be something like:
JTextField textField = new JTextField(20);
JFrame frame = new JFrame(...);
frame.add(textField, BorderLayout.PAGE_START);
frame.pack();
frame.setVisible(true);
There is no need to request focus on the text field. Focus will automatically be placed on the first component.
You may also want to take a look at the Swing tutorial on How to Make Dialogs. You can use a JOptionPane to prompt a user for text input. The tutorial has working examples.
field = new JTextField(40);
f.addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
field.requestFocus();
}
});
What are you doing here?
There is no textfield show in your code. All you have is a dialog... Do you need help making a textfield? How to add components to JDialog
Then after you make a text field select it by using textField.requestFocusInWindow()
or look at this post to help, Java Textfield focus

Java Swing blank screen instead of window displayed

I'm following through a book called "The JFC Swing Tutorial (Second Edition)" and I'm pretty much at the start I have followed this code and it should be displaying the button and the label in the content pane, but All im getting is a blank screen. any ideas?
Thanks.
import java.awt.GridLayout;
import javax.swing.*;
public class m extends JFrame
{
void UserFrame()
{
//JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Hellow You");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel jp = new JPanel(new GridLayout(0,1));
//makes label
JLabel label = new JLabel("Sup ");
//adds to the frames content pane a label
frame.getContentPane().add(label);
JButton button = new JButton("Hai");
frame.getContentPane().add(button);
jp.add(button);
jp.add(label);
jp.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
//pack set the window to what it needs AKA to display all components
frame.pack();
//frame.setSize(250, 250);
//shows window
frame.setVisible(true);
}
public static void main(String[] args)
{
final m window = new m();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
window.UserFrame();
}
});
}
}
Simply add
frame.add(jp);
just before
frame.pack();
What's happening here? You correctly add all your widgets to a JPane, but you basically threw that JPane away and didn't use it anywhere.
This will be sufficient just to get it to work properly.
If you want to do it correctly, you should also remove frame.getContentPane().add(label); and frame.getContentPane().add(button); (Thank you #dic19 for noting that!). These will not work the way you used it.

Swing: Showing a transparent Panel hovering over another Panel

I want to show a textArea showing some text (will show log lines) , and have an animated gif hoovering above it. I tried the solution described here , but all I get is a grey screen. Hints?
public class TestLayeredPanes {
private JFrame frame = new JFrame();
private JLayeredPane lpane = new JLayeredPane();
public TestLayeredPanes() {
frame.setPreferredSize(new Dimension(600, 400));
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
//Build the animated icon
JLabel buildingIcon = new JLabel();
buildingIcon.setIcon(new ImageIcon(this.getClass().getResource(
"/com/ct/tasks/cmviewer/gui/progress_bar.gif")));
JPanel iconPanel = new JPanel();
iconPanel.add(buildingIcon);
//Build the textArea
JTextArea textLog = new JTextArea("Say something");
JPanel textPanel = new JPanel();
textPanel.add(new JScrollPane(textLog));
//Add the panels to the layered pane
lpane.add(textPanel, 0);
lpane.add(iconPanel, 1);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new TestLayeredPanes();
}
}
Try putting your animated GIF on the glass pane of your root pane:
http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html
JXLayer make easier to do that. Look at JXLayer samples.
You also can take a look at code of XSwingX
Since you started with a working example, why did you remove lines of code from the example you copied?
Layered panes don't use a layout manager therefore the size of your components are (0, 0), so there is nothing to display. The setBounds(...) method in the example are there for a reason.

Categories