반응형

자바 프로그래머라면 당연히 AWT나 Swing 컴포넌트에 대해서 알고 있고 GUI를 위해서 여러 형태의 컴포넌트들을 조합해서 원하는 화면을 만들어 보았을 것이다. 그러나 때로는 JDK 에서 지원하는 표준 컴포넌트들만으로는 무엇인가 부족함을 느껴 본적은 없는가? 자신의 입맛에 딱 맞는 컴포넌트가 없어서 오랜 시간을 허비하거나 고생해본 경험이 있을 수도 있다. 이번 기사에서는 자신만의 간단한 컴포넌트를 작성해보기로 하자.

이번 소스에서 만들것은 CPU의 사용양을 윈도우의 작업 관리자에서 보이는 형태처럼 만드는 것이다. JProgressBar를 사용하면 비슷한 형태가 나오기는 하지만 아무래도 많이 다르다는 느낌이 들어서 직접 만들어서 사용하자.

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

public class PmTickChartPanel extends JPanel {
BorderLayout borderLayout1 = new BorderLayout();
JPanel centerPanel = new JPanel();
JPanel southPanel = new JPanel();
JPanel northPanel = new JPanel();
JLabel dataLabel = new JLabel();
GridLayout gridLayout1 = new GridLayout();
BorderLayout borderLayout2 = new BorderLayout();
JLabel titleLabel = new JLabel();
BorderLayout borderLayout3 = new BorderLayout();
JPanel westPanel = new JPanel();
JPanel eastPanel = new JPanel();

// 편의상 눈금은 10개만 보이고 색상 변경도 10 단위로만
int tickCount = 10;

Border centerPanelBorder;
private Border border1;

public PmTickChartPanel() {
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}

private void jbInit() throws Exception {
centerPanelBorder = BorderFactory.createLineBorder(Color.green, 1);
border1 = BorderFactory.createBevelBorder(BevelBorder.LOWERED, new Color(4, 4, 4), new Color(3, 3, 3), Color.black, Color.black);
this.setBackground(Color.black);
this.setForeground(Color.green);
this.setBorder(border1);
this.setLayout(borderLayout1);
centerPanel.setBackground(Color.black);
centerPanel.setFont(new java.awt.Font("Dialog", 0, 12));
centerPanel.setForeground(Color.green);
centerPanel.setBorder(centerPanelBorder);
centerPanel.setLayout(gridLayout1);
southPanel.setBackground(Color.black);
southPanel.setForeground(Color.green);
southPanel.setLayout(borderLayout2);
northPanel.setBackground(Color.black);
northPanel.setForeground(Color.green);
northPanel.setLayout(borderLayout3);
dataLabel.setBackground(Color.black);
dataLabel.setFont(new java.awt.Font("Dialog", 1, 12));
dataLabel.setForeground(Color.green);
dataLabel.setHorizontalAlignment(SwingConstants.CENTER);
dataLabel.setHorizontalTextPosition(SwingConstants.CENTER);
dataLabel.setText("");
titleLabel.setBackground(Color.black);
titleLabel.setFont(new java.awt.Font("Dialog", 1, 12));
titleLabel.setForeground(Color.green);
titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
titleLabel.setHorizontalTextPosition(SwingConstants.CENTER);
this.titleLabel.setText("CPU");
gridLayout1.setColumns(1);
gridLayout1.setRows(tickCount);
gridLayout1.setHgap(1);
gridLayout1.setVgap(1);
eastPanel.setBackground(Color.black);
eastPanel.setForeground(Color.green);
westPanel.setBackground(Color.black);
westPanel.setForeground(Color.green);
this.add(centerPanel, BorderLayout.CENTER);
this.add(southPanel, BorderLayout.SOUTH);
southPanel.add(dataLabel, BorderLayout.CENTER);
this.add(northPanel, BorderLayout.NORTH);
northPanel.add(titleLabel, BorderLayout.CENTER);
this.add(westPanel, BorderLayout.WEST);
this.add(eastPanel, BorderLayout.EAST);
setPreferredSize(new Dimension(90, 180));

for (int i = 0; i < tickCount; i++) {
Tick tick = new Tick(); // 눈금(tick)을 10개 생성하여 추가
this.centerPanel.add(tick);
}
}

/* 실제 컴포넌트에 값을 설정하면 눈금에 색상을 변경한다
* 값의 범위는 0~100 으로 하자
*/
public void setValue(int value) {
if (value > 100) { // 100을 넘어가면 100으로
value = 100;
}
else if (value < 0) { // 0보다 작으면 0으로
value = 0;
}

// 일단 전체 tick 을 검정색으로 칠하고
for (int j = 0; j < tickCount; j++) {
Tick tick = (Tick)this.centerPanel.getComponent(j);
tick.setBackground(Color.black);
tick.repaint();
}

// 입력된 value 값에 해당하는 tick들만 다시 녹색으로 칠한다
for (int i = 0; i < tickCount; i++) {
Tick tick = (Tick)this.centerPanel.getComponent(i);
if (tickCount - i > value / 10) {
// nothing to do
} else {
tick.setColor(Color.green);
tick.repaint();
}
}

// 하단에 숫자로 값을 표시
this.dataLabel.setText(value + " %");
}

public static void main(String args[]) {
JFrame frame = new JFrame(); // 테스트용 프레임을 생성하자
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
PmTickChartPanel tickPanel = new PmTickChartPanel();
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(tickPanel, BorderLayout.CENTER);

frame.setSize(300, 300);
frame.setVisible(true);

for (int i = 0 ; i < 100 ; i++) { // 테스트를 위해 값을 설정하는 부분
try {
Thread.sleep(100); // 잠시 쉬었다가
tickPanel.setValue(i); // 1씩 증가되는 값을 설정, 10 단위로 눈금 색상 변경
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}

/* 10 단위의 눈금 하나에 해당하는 컴포넌트
* 같은 값을 갖는 것이 좌우 하나씩 쌍으로 구성된다
*/
class Tick extends JPanel {
JPanel lPanel = new JPanel();
JPanel rPanel = new JPanel();
GridLayout layout = new GridLayout(1, 2);

public Tick() {
this.setBackground(Color.black);
this.setForeground(Color.black);
lPanel.setBackground(Color.black);
lPanel.setForeground(Color.green);
rPanel.setBackground(Color.black);
rPanel.setForeground(Color.green);
layout.setHgap(1);
setLayout(layout);
add(lPanel);
add(rPanel);
}

protected void setColor(Color color) {
lPanel.setBackground(color);
rPanel.setBackground(color);
}
}
<출처:ibm.com/developerworks/kr>

+ Recent posts