Java - JComponent


Gotovo sve Swing kontrole nasljeđuju klasu JComponent. Ovo je klasa koju nasljeđujemo ukoliko želimo i sami da kreiramo neki Swing korisnički interfejs, odnosno ako hoćemo da napravimo sopstvenu kontrolu. JComponent je nasljednik klase Container, koja je nasljednik klase Component (obe su deo java.awt paketa). Klasa JComponent je apstraktna, zbog čega se ne može instancirati.



Grafički prikaz kontrole

Ukoliko je u pitanju vizuelna kontrola, najbitniji metod kojim se prikazuje kontrola jeste metoda paint(). JComponent sadrži implementacije paint() i paintComponent() metoda, iako paint() metodu možemo koristiti direktno, preporučuje se korištenje paintComponent() metode. Njegovim korištenjem nećemo biti uskraćeni za aktivaciju paint() metoda, jer će paintComponent() u svakom slučaju aktivirati paint() metodu (kroz metodu update()), ali ćemo se time osloboditi obaveza aktivacije zasebnih paintBorder() i paintChildren() metoda, koje se aktiviraju unutar metode paint().


Krirajte novu klasu pod nazivom MyComponent i u nju ubacite sljedeći kod:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;

public class MyComponent extends JComponent
{
  @Override
  public void paintComponent(Graphics g)
  {
    g.setColor(Color.lightGray);
    g.fillRect(0, 0, 165, 20);
    g.setColor(Color.darkGray);
    g.drawString("Pozdrav iz moje komponente", 10, 15);
  }
}

Swing JComponent klasa, za razliku od AWT Component klase, ima ugrađen Double Buffering. Ukoliko ne želimo da opcija Double Bufferinga bude omogućena, možemo je isključiti (ili uključiti) metodom setDoubleBuffered(true/false). Ovaj metod možemo smjestiti unutar konstruktora klase.


Sljedeći kod smjestite unutar vaše Main klase:

import java.awt.FlowLayout;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;

public class Main
{
  public static void main(String[] args)
  {
    JFrame f = new JFrame();
    f.setLayout(new FlowLayout());
    f.setSize(300, 100);
    
    MyComponent mc = new MyComponent();
    f.add(mc);

    f.setDefaultCloseOperation(EXIT_ON_CLOSE);
    f.setVisible(true);
  }
}

Primetićemo da primjer neće dati dobar rezultat. Tačnije, kontrola će biti prikazana u vidu samo jedne tačke.




Ova pojava događa se unutar nekih Layouta koji ređaju kontrole jednu pored druge (na primer, FlowLayout) koristeći se njihovom veličinom. Da bismo je izbegli, moramo postaviti inicijalnu veličinu kontrole. Najbolje mesto za ovo je konstruktor. Sljedeći kod ubacite unutar klase MyComponent:

public MyComponent()
{
  setPreferredSize(new Dimension(165, 20));
}

Pogledajmo sada kompletna kod koji se nalazi u klasi MyComponent:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;

public class MyComponent extends JComponent
{
  @Override
  public void paintComponent(Graphics g)
  {
    g.setColor(Color.lightGray);
    g.fillRect(0, 0, 165, 20);
    g.setColor(Color.darkGray);
    g.drawString("Pozdrav iz moje komponente", 10, 15);
  }
  public MyComponent()
    {
        setPreferredSize(new Dimension(200, 20));
    }
}

Prikaz koda iz gornjeg primjera izgledaće ovako:




TooloTipText svojstvo

Svaka JComponent kontrola sadrži ToolTipText svojstvo. Ovo svojstvo predstavlja tekst koji će biti prikazan prilikom prelaska mišem iznad kontrole. Vrednost svojstva moguće je preuzeti ili postaviti metodima setToolTipText() i getToolTipText(). Pogledajmo primjer:

mc.setToolTipText("Ovo je tooltip!");

Prikaz kopletnog koda vaše Main klase:

import java.awt.FlowLayout;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;

public class Main
{
public static void main(String[] args)
{
    JFrame f = new JFrame();
    f.setLayout(new FlowLayout());
    f.setSize(300, 100);
    
    MyComponent mc = new MyComponent();
    f.add(mc);
    
    f.setDefaultCloseOperation(EXIT_ON_CLOSE);
    f.setVisible(true);
    
    mc.setToolTipText("Ovo je tooltip!");
    }
}

Kada naneste kursor miša na komponentu dobićete sljedeći rezultat:




Border

Border je interfejs kojim se predstavlja border svojstvo većine Swing komponenti. Border svojstvo postavlja se metodom setBorder(), a tip se instancira klasom BorderFactory:

this.setPreferredSize(new Dimension(165,20));
this.setToolTipText("Ovo je tooltip!");

Border svojstvo se ne mora postavljati iz imenovane instance, već ga je moguće postaviti i anonimno, ali se tada gubi smisao, jer podešeni okvir nije moguće dodjeliti ostalim komponentama:

this.setBorder(BorderFactory.createLineBorder(Color.yellow));

Klasa BorderFactory sadrži mnoštvo metoda za kreiranje različito stilizovanih okvira. Svaki metod, u odnosu na tip okvira, ima odgovarajući set parametara:

this.setBorder(BorderFactory.createLineBorder(Color.yellow, 3));

Sada ćemo pogledati kompletan kod i prikaz naše aplikacije:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.JComponent;

public class MyComponent extends JComponent
{
  @Override
  public void paintComponent(Graphics g)
  {
        g.setColor(Color.lightGray);
        g.fillRect(0, 0, 200, 20);
        g.setColor(Color.darkGray);
        g.drawString("Pozdrav iz moje komponente", 10, 15);
  }
  public MyComponent()
    {
        this.setPreferredSize(new Dimension(200,20));
        this.setToolTipText("Ovo je tooltip!");
        
        this.setBorder(BorderFactory.createLineBorder(Color.yellow));
        this.setBorder(BorderFactory.createLineBorder(Color.yellow, 3));              
    }
}

Prikaz koda iz gornjeg primjera izgledaće ovako:



this.setBorder(BorderFactory.createBevelBorder(1));



this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));



this.setBorder(BorderFactory.createMatteBorder(5, 5, 5, 5, Color.yellow));



this.setBorder(BorderFactory.createTitledBorder("Naslov bordera"));



Pogledajmo sada naš kompletan projekat:

1. Naša Main klasa:

import java.awt.FlowLayout;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;

public class Main
{
public static void main(String[] args)
{
    JFrame f = new JFrame();
    f.setLayout(new FlowLayout());
    f.setSize(300, 100);
    
    MyComponent mc = new MyComponent();
    f.add(mc);
    
    f.setDefaultCloseOperation(EXIT_ON_CLOSE);
    f.setVisible(true);
    }
}

2. Naša MyComponent klasa:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.border.EtchedBorder;

public class MyComponent extends JComponent
{
  @Override
  public void paintComponent(Graphics g)
  {
        g.setColor(Color.lightGray);
        g.fillRect(0, 0, 200, 50);
        g.setColor(Color.darkGray);
        g.drawString("Pozdrav iz moje komponente", 20, 35);
  }
  public MyComponent()
    {
        this.setPreferredSize(new Dimension(200,50));
        this.setToolTipText("Ovo je tooltip!");
        
        this.setBorder(BorderFactory.createBevelBorder(1));      
        this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
        this.setBorder(BorderFactory.createMatteBorder(5, 5, 5, 5, Color.yellow));
        this.setBorder(BorderFactory.createTitledBorder("Naslov bordera"));
    }
}

Svojstvo border se može podesiti i putem GUI Buildera. Potrebno je odabrati željeni tip okvira i prevući ga na kontrolu (ili jednostavno kliknuti lijevim tasterom miša jednom na okvir, a zatim na ciljnu kontrolu):




Okvir će odmah biti primenjen na kontroli, kao što je prikazano na sljedećoj slici:




Da bismo promenili podešavanja okvira, unutar svojstava kontrole (Properties) biramo opciju border:




Aktiviraće se alat Border customizer, pomoću koga možemo izmjeniti svojstva ili čak zamjeniti postojeći okvir nekim drugim: