Reputation: 25018
package test;
import javax.swing.*;
import java.awt.*;
public class TestWindow extends JFrame{
//------------------------------------------------------------------------------
public static void main(String[] args) {
new TestWindow();
}
//------------------------------------------------------------------------------
public TestWindow(){
setSize(300,300);
this.setUndecorated(true);
add(new Background());
setVisible(true);
}
//------------------------------------------------------------------------------
private class Background extends JPanel{
public Background(){
add(b);
repaint();
}
//------------------------------------------------------------------------------
Bubble b = new Bubble();
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Color c = Color.cyan;
g.setColor(c);
g.fillRect(0, 0,getWidth(), getHeight());
}
//------------------------------------------------------------------------------
private class Bubble extends JPanel{
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.green);
g.drawOval(0, 0, Background.this.getWidth(), Background.this.getHeight());
}
}
//------------------------------------------------------------------------------
}
}
The aim is to draw a cyan window with a green circle on it. Later I will add components to the green circle so it will look like there is a window with a cyan background and a green circle with components in it.
The output however is only the cyan background. No circle.
I tried setting XOR mode to cyan but that did not work either. Am I nesting the classes wrong?
Upvotes: 3
Views: 5852
Reputation: 347314
The major problem is here...
public void paintComponent(Graphics g){
super.paintComponent(g);
Color c = Color.cyan;
g.setColor(c);
g.fillRect(0, 0,getWidth(), getHeight());
add(b);
repaint();
}
Not only are adding components to your container within you paint method, you're also calling repaint, all this is going to conspire against you.
Paint is called by the repaint manager when ever your component needs to be updated, for all sorts of reasons. You should never call any methods that might invalidate it otherwise require the component to repainted, doing so will send you down slippery slope of CPU burn out.
Instead.
Bubble
component inside the constructor of the Background
componentgetPreferredSize
methods of both these components and provide useful hints so the layout managers have some idea of how much space the components might actually like to useThe major problem you are facing (other then the bad painting) is that the components are reporting themselves as requiring no height or width, meaning when the layout managers come to lay them out, they are effectively invisible
Update
I would recommend that you have a look at
Easter Egg
For taking advice and making an effort, let me give you a little help...
What I suggest you do is read through the code, go back to the Java Docs and tutorials and try and figure out what is going on ;)
public class CircleControl {
public static void main(String[] args) {
new CircleControl();
}
public CircleControl() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
add(new Bubble());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 300);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Color startColor = brighten(Color.CYAN, 0.75f);
Color endColor = brighten(Color.CYAN, 0.5f);
LinearGradientPaint lgp = new LinearGradientPaint(
new Point(0, 0),
new Point(0, getHeight()),
new float[]{0f, 1f},
new Color[]{startColor, endColor});
g2d.setPaint(lgp);
g2d.fill(new Rectangle(getWidth(), getHeight()));
g2d.dispose();
}
}
public class Bubble extends JPanel {
public Bubble() {
Font font = UIManager.getFont("Label.font");
setFont(font.deriveFont(Font.BOLD, 48));
setForeground(Color.WHITE);
setBackground(darken(Color.CYAN, 0.3f));
setOpaque(false);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
int x = (getWidth() - 150) / 2;
int y = (getHeight() - 150) / 2;
Color startColor = brighten(getBackground(), 0.05f);
Color endColor = getBackground();
LinearGradientPaint lgp = new LinearGradientPaint(
new Point(x, y),
new Point(x, y + 150),
new float[]{0f, 1f},
new Color[]{startColor, endColor});
g2d.setPaint(lgp);
g2d.fill(new Ellipse2D.Double(x, y, 150, 150));
FontMetrics fm = g2d.getFontMetrics();
x = x + ((150 - fm.stringWidth("22")) / 2);
y = y + ((150 / 2) + fm.getAscent());
g2d.setColor(getForeground());
g2d.drawString("22", x, y);
}
}
public static Color brighten(Color color, double fraction) {
int red = (int) Math.round(Math.min(255, color.getRed() + 255 * fraction));
int green = (int) Math.round(Math.min(255, color.getGreen() + 255 * fraction));
int blue = (int) Math.round(Math.min(255, color.getBlue() + 255 * fraction));
int alpha = color.getAlpha();
return new Color(red, green, blue, alpha);
}
public static Color darken(Color color, double fraction) {
int red = (int) Math.round(Math.max(0, color.getRed() - 255 * fraction));
int green = (int) Math.round(Math.max(0, color.getGreen() - 255 * fraction));
int blue = (int) Math.round(Math.max(0, color.getBlue() - 255 * fraction));
int alpha = color.getAlpha();
return new Color(red, green, blue, alpha);
}
}
Upvotes: 8
Reputation: 3521
I have run your code and made the changes.Here is it.However your program does not handle window closing. You have to write that.
package test;
import javax.swing.*;
import java.awt.*;
public class TestWindow extends JFrame
{
//------------------------------------------------------------------------------
public static void main(String[] args) {
new TestWindow();
}
//------------------------------------------------------------------------------
public TestWindow(){
setSize(300,310);
this.setUndecorated(true);
add(new Background());
setVisible(true);
}
//------------------------------------------------------------------------------
private class Background extends JPanel{
public Background(){
Bubble b = new Bubble();
add(b);
}
//------------------------------------------------------------------------------
@Override public Dimension getPreferredSize()
{
return new Dimension(300,300);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Color c = Color.cyan;
g.setColor(c);
g.fillRect(0, 0,getWidth(), getHeight());
}
//------------------------------------------------------------------------------
private class Bubble extends JPanel{
Bubble()
{
setOpaque(false);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.green);
g.fillOval(0, 0, getWidth(), getHeight());
}
@Override public Dimension getPreferredSize()
{
return new Dimension(300,300);
}
}
//------------------------------------------------------------------------------
}
}
Upvotes: 2