I've tried the add() method but nothing is displayed when I try to add Test to GraphicsTest. How should I be adding it? Can someone show me? I've included the code I'm using.
This is my way and it's not working. Can someone show me or make me aware of what the problem actually is?
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
public class Test extends JComponent
{
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.red);
g2d.drawString("Hello", 50, 50);
g2d.dispose();
}
}
Here is the other class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
public class GraphicsTest extends JPanel
{
private Graphics2D g2d;
private String state;
private int x, y;
GraphicsTest()
{
Test t = new Test();
t.setVisible(true);
add(t);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.drawString("STATE: " + state, 5, 15);
g2d.drawString("Mouse Position: " + x + ", " + y, 5, 30);
g2d.setColor(Color.red);
Rectangle2D r2d = new Rectangle2D.Double(x, y, 10, 10);
g2d.draw(r2d);
g2d.dispose();
}
public void setState(String state) { this.state = state; }
public String getState() { return state; }
public void setX(int x) { this.x = x; repaint(); }
public void setY(int y) { this.y = y; repaint(); }
}
Your problem is g2d.dispose(). Take those out and it should work. I suspect this may cause different behavior on different jvms. It appears what is happening is the g2d object is used to draw stuff on the GraphicsTest object. Then the same g2d object tries to draw stuff on on the Test object, but it has been disposed so it can't draw anything. There are cases where you want to call g2d.dispose() but this is not one of them.
The other thing I did to make your code work was I changed the layout manager:
setLayout(new BorderLayout());
add(t, BorderLayout.CENTER);
The default layout should be Flow Layout. I'm not sure off hand why it wouldn't work with Flow Layout.
Related
Hello I wonder if anyone can help me , I have declared 2 values x1, y1 both as 120 and trying to use these in the following method:
private void drawDot(int x, int y, Graphics2D twoD) {
twoD.fillOval(x-50, y-50, 100, 100);
}
However when I use drawDot(120,120,twoD) it paints the filled oval in the wrong place compared to when I manually use
twoD.fillOval(70,70,100,100);
Shouldn't these 2 statements do the exact same thing? Is there something I am missing? I have added an image to show the issue, the oval on the left is the oval drawn by my drawDot method and the oval on the right is the oval in the correct place as it should be. If anyone has any advice it would be greatly appreciated. Thanks
click this link to see how both ovals are drawn
the entire class:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DieFace extends JPanel {
int x1,y1 = 120;
int x2,y2 = 300;
int x3,y3 = 480;
private BufferedImage bufferedImage;
public DieFace() {
this.init();
this.frameInit();
updateVal(1);
}
private void init() {
this.setPreferredSize(new Dimension(600,600));
}
private void frameInit() {
JFrame window = new JFrame("Dice Simulation");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setContentPane(this);
window.pack();
window.setVisible(true);
window.setLocationRelativeTo(null);
}
public void paintComponent(Graphics g) {
Graphics2D twoD = (Graphics2D) g;
twoD.drawImage(bufferedImage,0,0,null);
}
private void drawDot(int x, int y, Graphics2D twoD) {
twoD.fillOval(x-50, y-50, 100, 100);
}
public void updateVal(int dieRoll) {
bufferedImage = new BufferedImage(600,600,BufferedImage.TYPE_INT_ARGB);
Graphics2D twoD = bufferedImage.createGraphics();
twoD.setColor(Color.WHITE);
twoD.fillRect(0, 0, 600, 600);
twoD.setColor(Color.BLACK);
if(dieRoll==1) {
drawDot(x1,y1,twoD);
twoD.fillOval(70, 70, 100, 100);
}
repaint();
}
}
Shouldn't these 2 statements do the exact same thing? Is there something I am missing?
Because you made a mistake in your variable initializations on x1, y1:
int x1,y1 = 120; //This means x1 = 0, y1 = 120
What you actually wanted is:
int x1 = 120, y1 = 120;
Since x1 is not 120, when you invoke
drawDot(x1,y1,twoD);
drawDot(0, 120, twoD); is being invoked
Hence both elipses will appear on the same y-axis, but different on the x-axis.
For an assignment we were asked to modify existing code to include more than one shape, more than one color, and to have the shapes move. I got a little carried away and started adding in more things but now we have an issue. All was going well until I added the left arm(as viewed on the screen). I am having a problem with a piece of the arm remaining in the previous place when moving the figure to the right. Up, down, and left are all working well, it is only to the right where I hit the problem. I have added a screenshot of what it looks like after I move the figures to the right two times. Thanks for any assistance you may be able to provide.
roboMan output
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.Color;
import java.awt.Polygon;
import java.util.Scanner;
import java.awt.geom.Ellipse2D;
public class SwingBot1 {
public static void main(String[] args) {
// contruction of new JFrame object
JFrame frame = new JFrame();
// mutators
frame.setSize(400,400);
frame.setTitle("SwingBot");
// program ends when window closes
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Robot r = new Robot();
frame.add(r);
// voila!
frame.setVisible(true);
// your Scanner-based command loop goes here
Scanner in = new Scanner(System.in);
boolean active = true;
while(active){
System.out.println("Enter \"up\", \"down\", \"left\", or \"right\" "
+ "to move.\nClose the window to quit.");
String direction = in.nextLine();
switch(direction){
case "up":
r.moveBot(0, -20);
break;
case "down":
r.moveBot(0, 20);
break;
case "right":
r.moveBot(20, 0);
break;
case "left":
r.moveBot(-20, 0);
break;
}
}
}
public static class Robot extends JComponent
{
private Rectangle rect = new Rectangle(45, 30, 20, 20);
int x = 30;
int y = 50;
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// set the color
g2.setColor(Color.RED);
// draw the shape`
g2.fill(rect);
Graphics2D g3 = (Graphics2D) g;
g3.setColor(Color.BLUE);
g3.draw(new Ellipse2D.Double(30, 50, 50, 100));
g3.fillOval(30, 50, 50, 100);
Graphics2D g4 = (Graphics2D) g;
g4.setColor(Color.GREEN);
g4.draw(new Line2D.Double(70, 141, 90, 190));
g4.draw(new Line2D.Double(39, 141, 30, 191));
Graphics2D g5 = (Graphics2D) g;
g5.setColor(Color.RED);
g5.draw(new Line2D.Double(80, 85, 125, 70));
//arm, left as viewed
g5.draw(new Line2D.Double(0, 70, 30, 85));
}
public void moveBot(int x, int y)
{
setX(getX()+x);
setY(getY()+y);
repaint();
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
/* public void moveBot(int x, int y)
{
// move the rectangle
rect.translate(x,y);
// redraw the window
poly.translate(x, y);
repaint();
}*/
}
}
It looks like you need to repaint the frame.
I have finally made a ticker that functions how I want it to, but the only problem now is that it seems kind of shaky and looks like it is being displayed on an old tv. How do I make it look smoother?
Here is my code:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Scroll1 extends JPanel{
private int x;
private int x2;
private int y;
private int width;
private String text;
private Font f=(new Font("SansSerif", Font.PLAIN,24));
public Scroll1(int startX)
{
x=Integer.MIN_VALUE;
x2=Integer.MIN_VALUE;
y=150;
text= "We are pleased to announce that Actavis has completed the acquisition of Auden Mckenzie, a dynamic and fast growing company focused on the development, licensing and marketing of generic medicines and proprietary brands in the UK. ";
}
#Override
public void paintComponent(Graphics g)
{
g.setFont(f);
if ( x == Integer.MIN_VALUE ){
width=g.getFontMetrics().stringWidth(text);
x = 0;
}
if ( x2 == Integer.MIN_VALUE ){
x2 = g.getFontMetrics().stringWidth(text);
}
g.setColor(Color.white);
g.fillRect(this.getX(), this.getY(), (int)this.getBounds().getWidth(), (int)this.getBounds().getHeight());
g.setColor(Color.black);
g.drawString(text, x, y);
g.drawString(text, x2, y);
}
public void start() throws InterruptedException{
while(true){
while(x>= (-width)&&x2!=Integer.MIN_VALUE){
x--;
x2--;
y = getHeight()/2;
Thread.sleep(15);
this.
validate();
repaint();
if(x2<=-width)
{
x2=width;
}
}
if(x<-width&&x!=Integer.MIN_VALUE)
{
x=width;
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Scrolling Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Scroll1 scrolling = new Scroll1(-100);
frame.getContentPane().add(scrolling);
frame.setSize(400, 300);
frame.setVisible(true);
try {
scrolling.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Call super.paintComponent before you perform custom painting
Prefer Swing Timer of a Thread, as Swing Timers are triggered within the EDT and you run less risk of having dirty reads between the paintComponent method and the Thread
paintComponent really shouldn't be making decisions about the rendering state, instead it should just paint the current state.
You don't need g.fillRect(this.getX(), this.getY(), (int) this.getBounds().getWidth(), (int) this.getBounds().getHeight());, just set the background color of the panel and allow the painting routines to do their jobs. Painting is done from 0x0, been the top/left corner of the component
There is an issue with your while loop in your start method which doesn't seem to allow it to run (at least in my testing)
Can you help me try to transfer it over to a swing timer or give me a good source to do so?
Can you pay me? ;)
First, getting it to be completely "stagger" free isn't going to be possible, as the process is reliant on the system's capability of keeping up to date with your requests. For example, you really don't need to it be running at > 60fps, seriously, 25fps or even 15fps would be more the suitable for what you are trying to do. You control the speed of the scroll by using the movement delta instead
The following example uses a Swing Timer, as did my previous example, but this example will also create a "continuous" loop, where if the amount of text been displayed is less then the width of the visible area, it will add a "new" message to trail it.
This example would be capable of display multiple different messages of varying lengths but I guess, that's a bonus
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Scroll1 extends JPanel {
private String text;
private Font f = (new Font("SansSerif", Font.PLAIN, 24));
private List<TickerTap> tickerTaps;
public Scroll1(int startX) {
text = "We are pleased to announce that Actavis has completed the acquisition of Auden Mckenzie, a dynamic and fast growing company focused on the development, licensing and marketing of generic medicines and proprietary brands in the UK.";
setFont(f);
setBackground(Color.WHITE);
tickerTaps = new ArrayList<>(4);
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
FontMetrics fm = getFontMetrics(getFont());
if (tickerTaps.isEmpty()) {
tickerTaps.add(new TickerTap(text, getWidth()));
}
TickerTap taps[] = tickerTaps.toArray(new TickerTap[tickerTaps.size()]);
int visibleWidth = 0;
for (TickerTap tap : taps) {
tap.move();
int messageWidth = fm.stringWidth(tap.getMessage());
if (tap.getxPos() <= -messageWidth) {
tickerTaps.remove(tap);
} else {
visibleWidth += tap.getxPos() + messageWidth;
}
}
while (visibleWidth < getWidth()) {
TickerTap last = tickerTaps.get(tickerTaps.size() - 1);
int xPos = last.getxPos() + fm.stringWidth(last.getMessage());
String message = " * " + text;
TickerTap next = new TickerTap(message, xPos);
visibleWidth += next.getxPos() + fm.stringWidth(next.getMessage());
tickerTaps.add(next);
}
repaint();
}
});
timer.start();
}
#Override
public 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);
for (TickerTap tap : tickerTaps) {
FontMetrics fm = g2d.getFontMetrics();
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.setColor(Color.black);
g2d.drawString(tap.getMessage(), tap.getxPos(), y);
}
}
public class TickerTap {
private String message;
private int xPos;
public TickerTap(String message, int xPos) {
this.message = message;
this.xPos = xPos;
}
public String getMessage() {
return message;
}
public int getxPos() {
return xPos;
}
public void move() {
xPos -= 2;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Scrolling Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Scroll1 scrolling = new Scroll1(-100);
frame.getContentPane().add(scrolling);
frame.setSize(400, 300);
frame.setVisible(true);
}
});
}
}
Take a look at How to use Swing Timers for more details. Timer is actually really to understand if you simply think of it like a kind of loop
Welp Mad Programmer you are a boss, thanks for all the help. I running what you had and it didnt work, strange huh? Anyway here is what I got now that seems to be working a whole lot smoother but still a few glitches here and there:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Scroll2 extends JPanel implements ActionListener{
private int x;
private int x2;
private int y;
private int width;
private String text;
private Font f=(new Font("SansSerif", Font.BOLD,34));
Timer t;
public Scroll2(int startX)
{
x=Integer.MIN_VALUE;
x2=Integer.MIN_VALUE;
y=150;
text= "We are pleased to announce that Actavis has completed the acquisition of Auden Mckenzie, a dynamic and fast growing company focused on the development, licensing and marketing of generic medicines and proprietary brands in the UK. ";
Timer refreshTimer = new javax.swing.Timer(10, this);
refreshTimer.start();
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setFont(f);
if ( x == Integer.MIN_VALUE ){
width=g.getFontMetrics().stringWidth(text);
x = 0;
}
if ( x2 == Integer.MIN_VALUE ){
x2 = g.getFontMetrics().stringWidth(text);
}
g.setColor(Color.white);
g.fillRect(this.getX(), this.getY(), (int)this.getBounds().getWidth(), (int)this.getBounds().getHeight());
g.setColor(Color.black);
g.drawString(text, x, y);
g.drawString(text, x2, y);
}
public void refresh ()
{
if(x>=(-width)&&x2!=Integer.MIN_VALUE)
{
x--;
x2--;
y = getHeight()/2;
}
if(x2<=-width&&x!=Integer.MIN_VALUE)
{
x2=width;
}
if(x<-width&&x!=Integer.MIN_VALUE)
{
x=width;
}
repaint();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Scrolling Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Scroll2 scrolling = new Scroll2(-100);
frame.getContentPane().add(scrolling);
frame.setSize(400, 300);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
this.refresh();
}
}
I have got problem with my project:/
Why drawPac isn't working correctly. Black rect is drawing, but my image not:/ why
I made 4 classes, here is cod of 3 classes, without main class which extends JFrame, and there is added JPanel Game.
File #1
package pacman;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Game extends JPanel {
Pac pacman = new Pac();
public void Game() {
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
}
#Override
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.fillRect(0, 0,this.getWidth(),this.getHeight());
drawPac(g2d);
}
public void drawPac(Graphics2D g2d){
g2d.drawImage(pacman.image, pacman.x, pacman.y, 100, 100, this);
}
}
File #2
package pacman;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Actor {
int x,y;
int dv;
Image image;
public void Actor(){
}
}
File #3
package pacman;
import pacman.Game;
import javax.swing.ImageIcon;
import java.awt.Graphics2D;
public class Pac extends Actor {
public void Pac(){
try{
image = new ImageIcon(Pac.class.getResource("../img/Pac00.gif")).getImage();
x=0;
y=0;
}
catch (Exception e){
System.out.println("Blad prz otwieraniu");
System.exit(0); }
}
}
1 - The "Pac" class should be responsible for draw itself, don't you agree?
2 - For JPanels and every JComponent's sons, you should override the paintComponent method, not paint, that is responsible to delegate the painting work to paintComponent, paintBorder and paintChildren. You should call the super version of paintComponent too, as you are doing in paint. Take a look at the documentation.
3 - In most of the cases, is recomended to create a new graphics context (based on the original). So, your line:
Graphics2D g2d = (Graphics2D) g;
Should be replaced to:
Graphics2D g2d = (Graphics2D) g.create();
And you need to dispose (g2d.dispose()) this new context after using it (at the last line of the paintComponent).
4 - Is the code of the Pac class correct? Is it compiling? The image field is a member of Actor?
I think you have some problems in your code that you not showed in your question...
Ok #lechniak update Game class
public class Game extends JPanel {
Pac pacman = new Pac();
public Game() {
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
}
#Override
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
drawPac(g2d);
}
public void drawPac(Graphics2D g2d){
g2d.drawImage(pacman.image, pacman.x, pacman.y, 200, 200, this);
}
public static void main(String[] args) {
JFrame f = new JFrame("Image Draw");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new Game());
f.setSize(350,300);
f.setLocation(300,300);
f.setVisible(true);
}
}
And Pac class
//import javax.swing.ImageIcon;
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import javax.imageio.ImageIO;
import java.io.*;
public class Pac /*extends Actor*/ {
int x = 0;
int y = 0;
BufferedImage image;
public Pac() {
try {
image = ImageIO.read(new File("/Users/hlozano/java/swing/programmerBorn.jpg"));
//new ImageIcon(Pac.class.getResource("../img/Pac00.gif")).getImage();
x = 0;
y = 0;
} catch (Exception e) {
System.out.println("Blad prz otwieraniu " + e);
System.exit(0);
}
}
}
And image output
I hope these helps.
I have a Graphics object of JPanel and that is working fine:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
public class GraphicsTest extends JPanel
{
private Graphics2D g2d;
private String state;
private int x, y;
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.setClip(0, 0, getWidth(), getHeight());
g2d.setColor(Color.BLACK);
g2d.drawString("STATE: " + state, 5, 15);
g2d.drawString("Mouse Position: " + x + ", " + y, 5, 30);
g2d.setColor(Color.red);
Rectangle2D r2d = new Rectangle2D.Double(x,y,10,10);
g2d.draw(r2d);
Test t = new Test();
super.add(t);
repaint();
}
public void setState(String state) { this.state = state; }
public String getState() { return state; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
}
I was experimenting with a new Graphics component and when I instantiate a new Test and add it in GraphicsTest nothing happens. What is it that I am doing wrong?
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;
public class Test extends JComponent
{
private Graphics2D g2d;
private String state;
private int x, y;
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g2d = (Graphics2D) g.create();
g2d.setColor(Color.GREEN);
g2d.fill(new Rectangle2D.Double(60, 60,
10, 10));
repaint();
}
public void setState(String state) { this.state = state; }
public String getState() { return state; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
}
Thanks!
You should add Test component only once and set a layout:
public GraphicTest()
{
super();
setLayout(new BorderLayout());
add(new Test(),BorderLayout.CENTER);
}
Also, do not save Graphics2D objects because they will be invalid once paintComponent is finished and do not call repaint inside paintComponent. Use timers if you need animation and call repaint in setXXX methods that change the look of the component.