JFrame text displaying wrong - java

I am creating an app that uses an undecorated border and wanted to add a shadow to the my JFrame. I got the shadow working but in the process the text got all screwed up.
Due to the size of the program I can not post all of my code but the problem does go away when I remove this line.
setBackground(new Color(0, 0, 0, 0));
So what could cause the text to display blurry and incorrectly? It is bolder and some of the letters seem to be taller.
And I cannot post a picture since I do not have a level 10 reputation.
Here is more of my code:
int extendBy=30;
setMaximumSize(new Dimension(width + extendBy, height + extendBy));
setMinimumSize(new Dimension(width + extendBy, height + extendBy));
setPreferredSize(new Dimension(width + extendBy, height + extendBy));
setUndecorated(true);
setBackground(new Color(0, 0, 0, 0)); // all hell breaks loose here
setContentPane(new ShadowPane());
getContentPane().setBackground(Color.BLACK);
setLocationRelativeTo(null);
setLayout(null); // I know setting null this is bad practice
edit: acquired 10 reputation so here is a pic (look at W or A or k):

Try to override the paintComponent method for this JTable.
How to do it: Overriding paintComponent
For Your case i would use anti-aliasing to get rid of those unwanted effects.
jTable1 = new javax.swing.JTable(){
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON );
}
};

Related

How to fix the look of rendered string in Java

I am drawing a string in a JPanel with a pixel font. Some parts of the letters are drawn with extra pixels so it looks wider. How can I remove those extra pixels? Here's what it looks like.
public void paintComponent(Graphics g) {
Graphics2D gtd = (Graphics2D) g;
gtd.setFont(new Font("EXEPixelPerfect", Font.PLAIN, 50));
gtd.drawString("continue", 100, 100);
gtd.setFont(new Font("EXEPixelPerfect", Font.PLAIN, 51));
gtd.drawString("continue", 100, 150);
gtd.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
gtd.setFont(new Font("EXEPixelPerfect", Font.PLAIN, 50));
gtd.drawString("continue", 100, 200);
}
The first text is what I have originally. As you can see in the picture, some parts are wider.
In the second text, I increased the font size by one. I want it to look like that, but it's still not fixed. A part of 'e' looks wider.
The third text has the same font format with the first text but it has anti-alias. It fixed the wide lines but the problem is, it looks blurry.

why isn't an oval displayed in my jPanel? [duplicate]

This question already has answers here:
Can not draw oval on a JPanel
(2 answers)
Closed 2 years ago.
I'm trying to add a circle to my JPanel, but it won't draw the cricle.
the code below creates a JFrame, creates a JPanle and calls a function to add a circle to the JPanel(pgame), but it doesn't actually add it.
Help appreciated
fgame = new JFrame("Backgammon");
fgame.setSize(1000, 1000);
pgame = new JPanel();
pgame.setPreferredSize(new Dimension(1000, 687));
pgame.setLayout(new GridLayout(3, 10));
pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
Circle Circlepanel = new Circle();
pgame.add(Circlepanel);
Circlepanel.setVisible(true);
fgame.add(pgame,BorderLayout.CENTER);
fgame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fgame.setTitle("Backgammon");
fgame.pack();
fgame.setVisible(true);
public class Circle extends JPanel {
public void paint(Graphics g) {
g.drawOval(500, 500, 100, 100);
g.setColor(Color.RED);
g.fillOval(500, 500, 100, 100);
}
}
First of all variable names should NOT start with an upper case character. Most of you names are correct, but not all. Learn Java conventions and be consistent!
Your create a GridLayout
pgame.setLayout(new GridLayout(3, 10));
Which will attempt to allocate space for 3 components vertically in the frame.
Then you create a Border:
pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
which will give your component a height of 459 and a width of 920.
Finally you try to draw the oval at (500, 500) from the top left of the panel.
g.drawOval(500, 500, 100, 100);
Well, the problem is that you have weird random numbers and the size of your component isn't large enough to paint the oval in the space of the component.
To demonstrate this add and retest:
Circlepanel.setBackground( Color.YELLOW );
You will see a yellow panel. Next change:
//pgame.setLayout(new GridLayout(3, 10));
pgame.setLayout(new GridLayout(1, 0));
and you will see a taller yellow panel in the middle of the frame because you are only allocating space for a single component.
Next change:
//pgame.setBorder(BorderFactory.createEmptyBorder(309,460,150,460));
pgame.setBorder(BorderFactory.createEmptyBorder(50,50,50,50));
and you will see part of the oval because you have reserved less space for the border.
Next change:
//g.fillOval(500, 500, 100, 100);
g.fillOval(0, 0, 100, 100);
and you will see the oval at the top of the panel.
The point is that specifying the:
grid size
border size
oval location
all affect the size of the component and how it is painted.
Other issues:
override the getPreferredSize() method of your Circle class to return the desired size of the panel
custom painting is done by overriding paintComponent(), not paint();
you need to invoke super.paintComponent(..) at the start of the method.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.

Does JFrame not accurately display specified width and height values?

I'm building a simple 2D game in Java.
I'm using the JFrame class, but I don't think the width and height are what I specified, or perhaps the graphics are incorrect.
Here are some snippets of my code:
public final static int WIDTH = 600, HEIGHT = 900;
JFrame frame = new JFrame();
frame.setSize(WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.fillRect(0, 0, WIDTH, HEIGHT - 10);
The JFrame is displaying a black background. However, based on the arguments I gave to the fillRect function, there should still be a 10px tall sliver of white at the bottom of the frame. This is not the case. The white sliver only really starts to show after a 30px decrease from the height of the frame.
Thanks for your help.
The JFrame size includes the borders so you need to allow for them. To facilitate dealing with this don't specify the width and height of the JFrame. I recommend doing the following.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(width,height));
frame.add(panel);
// add other components in the panel
frame.pack();
// center on screen.
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Now your panel will be the specified size.
Note, if your going to paint, make certain you override paintComponent(Graphics g) in JPanel and do your painting there.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// your code here
}

Java Project changing behaviour

I have been working on a basic Java Swing application, that paints some objects into a opaque JPanel. I have been coding this app on a University MAC-PC. Yesterday I tested the program on my macbook air(after exporting the project), the behaviour of the application totally change.
The logic of the application is as follows, a Jframe that contains a JLayeredPaneL with Jpanel, in each Jpanel I paint some objects.The application is working correctly on the University laptop.
1)The JPanel is not longer transparent
//Creating Layered Panel
JLayeredPane lpane = new JLayeredPane();
lpane.setBounds(0, 0, screenSize.width, screenSize.height);
this.add(lpane, BorderLayout.CENTER);
lpane.setBounds(0, 0, screenSize.width, screenSize.height);
//creating Jpanel
myGlassPane = new JPanel()
myGlassPane.setBackground(new Color(0, 255, 0, 0));
myGlassPane.setBounds(0, 0, 400, 400);
myGlassPane.setOpaque(true);
myGlassPane.setVisible(true);
//adding item
lpane.add(myGlassPane);
this.setBackground(new Color(0, 255, 0, 0));//makes JFrame invisible
this.setVisible(true);
this.setResizable(false);
2) The JPanel does not remember what is previously drawn(it actually creates two Jpanel one what is being drawn at the moment and what was previously drawn)
I paint lines, whenever a new line is added to an array I call paintAgain(), here is the code of the paintComponent
public void paintLines(Point p)
{
arrayLines.add(p);
repaint();
//Only the point is displayed the other points are not visible,
//the other points are in another JPANEL?
}
public void delete()
{
delete = true;
arrayLines.clear();
repaint();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(delete)
{
g.clearRect(0,0,screenSize.width,screenSize.height);
delete =false;
}
else
{
g2d = (Graphics2D) g.create();
g2d.setStroke(new BasicStroke(10));
g2d.setColor(pickedColor);
//It just paints the new lines, it does not iterate through all the points
g2d.draw(new Line2D.Float(arrayLines.get(arraySize-1).getx1(), arrayLines.get(arraySize-1).gety1(),arrayLines.get(arraySize-1).getx2(),arrayLines.get(arraySize-1).gety2()));
}
}
I do not know why the behaviour of the program changes. Maybe the JRE version that i'm using?I have literally no idea since, it has never happened before
Thank you in advance
In your paintComponent method, your code as written just draws one line, and so one line is all that you see. Instead you need to use a for loop to iterate through your Point collection, arrayLines, drawing a line between points.
// note that i *must* start at 1, not at 0
for (int i = 1; i < arrayLines.size(); i++) {
int x1 = arrayLines.get(i - 1).x;
int y1 = arrayLines.get(i - 1).y;
int x2 = arrayLines.get(i).x;
int y2 = arrayLines.get(i).y;
g2.drawLine(x1, y1, x2, y2);
}
Also, where do you set delete to true ever?
Edit
Regarding your comments:
...The paint method is an example, I call paintLines() several times.
This won't matter if paintComponent draws one and only one line.
Do I have to repaint everything , everytime i make a modification in the array?
At this point, probably, yes. Later consider doing your static background drawing to a BufferedImage and then displaying that in the paintComponent almost first thing, right after the super.paintComponent(g) call, and then drawing your non-static, your moving sprites directly in paintComponent. If you know for a fact that you've only altered a portion of a component, you can call one of the repaint(...) overload methods that suggest repainting a rectangular area of the component.
The problem is this code is working in another computer and in mine it misbehaves.
The issue for me is that I have no idea why the code would have a prayer of working on another system since it is broken code.
One of the other issues you are having is the fact that you are using an alpha based color as the background to an opaque component...
myGlassPane = new JPanel()
myGlassPane.setBackground(new Color(0, 255, 0, 0));
myGlassPane.setBounds(0, 0, 400, 400);
myGlassPane.setOpaque(true);
myGlassPane.setVisible(true);
//adding item
lpane.add(myGlassPane);
Swing only knows how to paint opaque or transparent components and makes these decisions based on the opaque state of the components.
When transparent, the API knows that it must first prepare the graphics context properly and secondly, paint all components that might be beneath this one.
When using an alpha based background color, the component is unable to clear the Graphics context for painting (as filling with a transparent color doesn't do anything), this tends to mean that the Graphics context still contains what ever was painted to it previously (as the Graphics context is a shared resource).
Instead, remove...
myGlassPane.setBackground(new Color(0, 255, 0, 0));
and use
myGlassPane.setOpaque(false);
which will give you the same effect.
It will also mean you won't need
g.clearRect(0,0,screenSize.width,screenSize.height);
and can simply remove the all the elements from the arrayLines instead, which will give you the same effect...just longer lasting...

Why is my JPanel smaller than it should be?

I am trying to learn Swing and have made a panel (with help from other StackOverflow code). I added a checkerboard design on a frame, but I have found that the frame is not as big as it should be.
Here is my code:
#Override
protected void paintComponent(Graphics g) {
int width = getWidth(), height = getHeight();
g.clearRect(0, 0, width, height);
g.setColor(Color.BLACK);
for (int i=0;i<=width;i+=50) {
g.drawLine(0,i,width,i);
}
for (int i=0;i<=height;i+=50) {
g.drawLine(i,0,i,height);
}
label.setText("H = "+ getHeight() +" W = "+ getWidth()); // check actual size
add(label);
}
private void gui(Pan window) {
frame = new JFrame();
Container container = frame.getContentPane();
container.add(window);
frame.setSize(400, 400); // size written here
frame.setVisible(true);
}
If you run it, you'll see the size of the window. It will be 362 by 384, instead of 400 by 400 as written in the code.
If I change the dimensions to 500 by 500, the window will be 462 by 484.
Q: Why are the dimensions off by 38 and 16?
It will be 362 by 384, instead of 400 by 400
Because the size of the frame include the title bar and borders. Don't use the setSize() method.
Instead override the getPreferredSize() method of your custom panel to return the size that you want the panel to be.
Then you use:
frame.pack();
Then the size of the frame will be the preferred size of your panel, plus the size of the title bar and borders.

Categories

Resources