Formatting a frame in java swing

OS - Windows 10 TextEditor - VSCode

Am having trouble getting rid of a white outline around my frame in the below program. I have a black desktop and am attempting to get the application to blend in to be run as a widget. Yet, I haven't been able to find any methods in swing that seem to get rid of the white outline in question.

The code is below so you can run it and see what I have tried, and all that good stuff. I have comment out bits and pieces that I was experimenting with to see if the would change anything. Also have a text field that gets a date and time output from another class file I have made, so just ignore that in regards to this question. Unless formatting the text field in some way may fix the problem.

I have scrolled through all the methods that swing provides and I cannot find one that appears to solve my problem. Although the chances I missed it are 100%.

import java.awt.*;
import javax.swing.*;

public class GUI implements GUIInterface{
    
    private JFrame frame;
    private JPanel panel;
    //private JLabel label;
    private JTextField txt;

    GUI(DateAndTime current){
        
        //label = new JLabel("Time");
        //label.setBounds(10,20,80,25);

        txt = new JTextField();
        txt.setEditable(false);
        txt.setBounds(0, 0, 130, 80);
        txt.setBackground(Color.BLACK);
        txt.setFont(new Font("Arial", Font.BOLD, 12));
        //txt.setOpaque(false);
        txt.setHorizontalAlignment(JTextField.CENTER);
        txt.setText(" " + current.toString() + " ");

        panel = new JPanel();
        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        panel.setLayout(new GridLayout());
               

        //panel.add(label);
        panel.add(txt);

        frame = new JFrame();
        //frame.setIconImage();
        frame.setUndecorated(true);
        frame.getContentPane().setForeground(Color.BLACK);
        frame.getContentPane().setBackground(Color.BLACK);
        //frame.setOpacity(0.95f);
        //frame.setBounds(200, 100, 120, 70);;
        //frame.setShape();
        //frame.setGlassPane(new Component() );
        //frame.setDefaultLookAndFeelDecorated(true);        
        frame.setMinimumSize(new Dimension(130, 80));
        frame.setMaximumSize(new Dimension(130, 80));
        frame.setResizable(false);    
        frame.setLocation(200,100);    
        //frame.setTitle("Time");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                       
        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);

        while(true){
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException ex)
            {
                break;
            }
            current.incSecond();
            System.out.print("\r                                          \r" + current.toString()); // outputs to command window
            txt.setText(" " + current.toString() + " ");  // outputs to GUI textField
        }
    }

}

Upvotes: 0

Views: 267

Answers (2)

camickr
camickr

Reputation: 324128

The white line is the Border of the text field:

Try:

txt.setBorder(new EmptyBorder(0, 0, 0, 0));

Also, don't use a while (true) loop. For animation use a Swing Timer.

Upvotes: 2

MadProgrammer
MadProgrammer

Reputation: 347234

For me, the issue is coming from the JPanel (panel = new JPanel();) you create to hold the JTextField.

When running on MacOS, there is "empty" space around the field, which is used by the Look and Feel to provide a visual clue about which component has focus (I'm guessing).

I tested this by setting the background color of the panel to red...

Example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class GUI {

    private JFrame frame;
    private JPanel panel;
    //private JLabel label;
    private JTextField txt;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new GUI();
            }
        });
    }

    GUI() {
        txt = new JTextField(8);
        txt.setEditable(false);
        txt.setBounds(0, 0, 130, 80);
        txt.setBackground(Color.BLACK);
        txt.setFont(new Font("Arial", Font.BOLD, 12));
        txt.setHorizontalAlignment(JTextField.CENTER);
        txt.setText(" Hello ");

        panel = new JPanel();
        panel.setBorder(new EmptyBorder(20, 20, 20, 20));
        panel.setLayout(new BorderLayout());

        panel.add(txt);

        frame = new JFrame();
//        frame.setUndecorated(true);
        frame.getContentPane().setForeground(Color.BLACK);
        frame.getContentPane().setBackground(Color.BLACK);
//        frame.setMinimumSize(new Dimension(130, 80));
//        frame.setMaximumSize(new Dimension(130, 80));
//        frame.setResizable(false);
        frame.setLocation(200, 100);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        panel.setBackground(Color.RED);
        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);

//        while (true) {
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException ex) {
//                break;
//            }
//            current.incSecond();
//            System.out.print("\r                                          \r" + current.toString()); // outputs to command window
//            txt.setText(" " + current.toString() + " ");  // outputs to GUI textField
//        }
    }

}

Swing is also single threaded and nit thread safe. This means you shouldn't be performing any long running or blocking operations on the event dispatching thread and you shouldn't be updating the UI (or any state the UI relies on) from outside the context of the event dispatching thread.

See Concurrency in Swing for more details and How to Use Swing Timers for a better solution.

Also, as a side note, when posting code, try and remove everything which isn't been used to demonstrate the problem, makes it easier ;)

Upvotes: 1

Related Questions