---
title: "Java 정리 24"
date: "2018-12-14"
tags: ["Java"]
status: archived
verified: false
---

## Java 정리 24 - ImageIcon, Border, JOptionPane, JScrollPane, JList

---

### 아이콘 사용

* JButton, JLabel, JCheckBox, JRadioButton 생성자를 보면 Icon을 파라미터로 받을 수 있다.
  * AWT와는 다르게 RadioButton 제공
* **이미지를 쉽게 사용할 수 있다.**
* **ImageIcon 클래스를 이용**
  * 모든 포맷의 이미지를 넣을 수 있음
  * **Tooltip Text** - 풍선 도움말 기능
  * **Roll Over** - 마우스 커서가 해당 컴포넌트에 올라가면 다른 이미지로 바뀌는 것

```java
// 이미지 로딩, 경로 표현시 '\\'나 '/'를 사용(권장)    
ImageIcon ii = new ImageIcon("경로");

// 필요한 컴포넌트에서 사용(has-a)
JButton jb = new JButton(ii);
```

```java
/**
* Icon class를 사용한 이미지 사용
* @author owner
*/
public class UseImageIcon extends JFrame {
  
  public UseImageIcon() {
    super("ImageIcon사용");
    
    ImageIcon ii1 = new  ImageIcon("C:/.../ebichuPng.png");
    ImageIcon ii2 = new  ImageIcon("C:/.../ebichuPng2.png");
    ImageIcon ii3 = new  ImageIcon("C:/.../ebichuPng3.png");
    ImageIcon ii4 = new  ImageIcon("C:/.../ebichuGif.gif");

    JButton btn1 = new JButton("버튼1", ii1);
    JButton btn2 = new JButton("버튼2", ii2);
    JButton btn3 = new JButton("버튼3", ii3);
    
    // JComponent클래스의 setTooltipText메소드로 tooltip text(풍선 도움말) 추가
    btn1.setToolTipText("버튼1");
    btn2.setToolTipText("버튼2");
    btn3.setToolTipText("버튼3");
    
    // RollOver icon (마우스 커서 올리면 이미지가  바뀌는 것)
    btn1.setRolloverIcon(ii4);
    
    // 버튼의 라벨(글자) 위치 변경
    // 가로 위치 변경 : LEFT, CENTER, RIGHT
    btn1.setHorizontalTextPosition(JButton.LEFT);
    btn2.setHorizontalTextPosition(JButton.RIGHT);
    btn3.setHorizontalTextPosition(JButton.CENTER);
    
    // 세로 위치 변경 : TOP, CENTER, BOTTOM
    btn1.setVerticalTextPosition(JButton.TOP);
    btn2.setVerticalTextPosition(JButton.CENTER);
    btn3.setVerticalTextPosition(JButton.BOTTOM);
    
    setLayout(new GridLayout(1,3));
    add(btn1); add(btn2); add(btn3);
    setBounds(150, 200, 800, 300);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  public static void main(String[] args) {
    new UseImageIcon();
  }
}
```

![01](/md/legacy-assets/java/24/01.webp)


---

### Border

![02](/md/legacy-assets/java/24/02.webp)

* 위 그림 엷은 테두리를 Border라고 한다. 
* **javax.swing.border 패키지**에서 관련 클래스를 제공
* 테두리가 없는 **모든 Component**에 테두리를 적용할 때 사용
* 타이틀이 있는 테두리(**TitledBorder**)가 가장 많이 사용됨
  * 보통 **패널에 많이 사용**

```java
// 1. Border를 생성
TitledBorder tb = new TitledBorder("타이틀에 들어갈 메세지");

// 2. Component에 적용, JComponent의 setBorder 메소드 사용
컴포넌트객체.setBorder(tb);
```

---

### 한줄 입력 받기

* 일반 문자를 입력 받을 땐 **JTextField** 사용
  * 입력값을 가져올 때 **getText** 사용
* **JPasswordField**
  * 비밀번호를 입력받을 때 사용
  * **AWT의 TextField**는 비밀번호 입력받을 때 **setEchoChar**를 사용
  * 입력값을 가져올 때 **getPassword** 사용
    * **char[]**로 반환하는데 이를 String으로 만들기 위해 **String생성자 호출**
  
```java
// char[]를 String으로 변환하기
char[] c = {'a','b','c'};

String s2 = new String(c);
System.out.println(s2);
```

---

### Border 사용 예제

* Border로 각 컴포넌트들을 감싸고 JTextField와 JPasswordField 입력값을 출력 라벨에 표기
  * 아이디 admin, 비밀번호 123이 입력시 구현한 메모장 호출

![03](/md/legacy-assets/java/24/03.webp)

```java
public class UseTitledBorder extends JFrame implements  ActionListener {
  private JTextField jtfId;
  private JPasswordField jpfPw;
  private JLabel jlOutput;

  public UseTitledBorder() {
    super("Border 사용");
    jtfId = new JTextField();
    jpfPw = new JPasswordField();
    jlOutput = new JLabel();

    jtfId.setBorder(new TitledBorder("아이디"));
    jpfPw.setBorder(new TitledBorder("비밀번호"));
    jlOutput.setBorder(new TitledBorder("출력창"));

    JPanel panel = new JPanel();
    panel.setBorder(new TitledBorder("로그인"));

    panel.setLayout(new GridLayout(3, 1));
    panel.add(jtfId);
    panel.add(jpfPw);
    panel.add(jlOutput);

    jtfId.addActionListener(this);
    jpfPw.addActionListener(this);

    add(BorderLayout.CENTER, panel);
    setBounds(100, 100, 250, 300);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  @Override
  public void actionPerformed(ActionEvent ae) {
    String id = jtfId.getText().trim();
    
    // 아이디에서 이벤트가 발생하면
    if (ae.getSource() == jtfId) {
      // 아이디에 값이 들어있다면 커서를 비밀번호로  이동
      if (!id.equals("")) {
        jpfPw.requestFocus();
      }
    }
    // 비밀번호에서 이벤트가 발생하면
    if (ae.getSource() == jpfPw) {
      // 아이디에 값이 없다면 커서를 아이디로 이동,
      if (id.equals("")) {
        jtfId.requestFocus();
        jlOutput.setText("아이디를  입력해주세요.");
        
        // 반환형이 void인 메소드에서 코드의  실행을 멈추고
        // 호출한 곳으로 돌아가라는 의미
        return;
      }
      String pw = new String(jpfPw.getPassword());
      // 비밀번호에 값이 없다면 출력창에  "비번입력"을 보여주고 커서를 비밀번호로 이동
      if(pw.trim().equals("")) {
        jlOutput.setText("비밀번호를  입력해주세요.");
        return;
      }
      // 비밀번호에 값이 있다면 아이디가 admin,  비밀번호가 123과 같은지
      // 비교하여 같다면 자바메모장 클래스를 실행
      if(id.equals("admin") && pw.equals("123")) {
        new JavaMemo();
        dispose();
      } else {
        jlOutput.setText("아이디나 비밀번호를  확인해주세요.");
      }
    }
  }
  public static void main(String[] args) {
    new UseTitledBorder();
  }
}
```

![04](/md/legacy-assets/java/24/04.webp)

---

### LineBorder

* 생성자에서 Color를 받음
* 마찬가지로 모든 컴포넌트에 설정 가능
*** 컴포넌트 주변을 색있는 Border로 강조가능**

```java
// LineBorder 생성
LineBorder lb = new LineBorder(Color.BLACK);

// 컴포넌트에 설정
컴포넌트.setBorder(lb);
```

```java
public class UseLineBorder extends JFrame implements  ActionListener {
  private JButton btn1, btn2;
  public UseLineBorder() {
    super("LineBorder");
    
    btn1 = new JButton("확인");
    btn2 = new JButton("취소");
    
    JPanel panel = new JPanel();
    
    panel.add(btn1);
    panel.add(btn2);
    panel.setBorder(new LineBorder(Color.RED));
    
    setLayout(null);
    
    panel.setBounds(200, 350, 135, 40);
    add(panel);
    
    
    setBounds(100, 100, 410, 450);
    setVisible(true);
    setResizable(false);
    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  
  @Override
  public void actionPerformed(ActionEvent e) {
        
  }
  
  public static void main(String[] args) {
    new UseLineBorder();
  }
}
```

![05](/md/legacy-assets/java/24/05.webp)

---

### JOptionPane

![06](/md/legacy-assets/java/24/06.webp)

* **Dialog를 미리 구현해 놓은 클래스**
* 객체생성없이 **static 메소드를 바로 사용**
* **부모 창이 없어도 창을 띄울 수 있다.**
* **입력받기 (InputDialog)**
  * **showInputDialog** 호출
    * 메시지를 보여주고 값을 받을 수 있는 Dialog 나타남
    * 받은 메시지가 String형으로 반환됨

![07](/md/legacy-assets/java/24/07.webp)

```java
String s = JOptionPane.showInputDialog("메시지", "초기값");
```

* **메시지 제공하기 (MessageDialog)**
  * **showMessageDialog** 호출
    * 경고 메시지만 보여주는 Dialog 나타남, 반환형 void
  * 부모창이 없어도 됨

![08](/md/legacy-assets/java/24/08.webp)

```java
JOptionPane.showMessageDialog(프레임인스턴스, "메시지", "타이틀", JOptionPane아이콘필드);
```

* **사용자의 의중 얻기 ConfirmDialog**
  * **showConfirmDialog** 호출
    * 반환형 int
      * **Yes - 0 = JOptionPane.OK_OPTION**
      * **No - 1 = JOptionPane.NO_OPTION**
      * **Cancel - 2 - JOptionPane.CANCLE_OPTION**
  * 부모창이 없어도 됨

![09](/md/legacy-assets/java/24/09.webp)

```java
JOptionPane.showConfirmDialog(프레임인스턴스, "메시지");
```

```java
public class UseJOptionPane extends JFrame implements ActionListener {

  private JButton btn1, btn2, btn3;
  private JLabel jlOutput;
  
  public UseJOptionPane() {
    super("jOptionPane 사용");
    
    btn1 = new JButton("Input Dialog");
    btn2 = new JButton("Message Dialog");
    btn3 = new JButton("Confirm Dialog");
    
    jlOutput = new JLabel("출력");
    jlOutput.setBorder(new TitledBorder("출력창"));
    
    JPanel panel = new JPanel();
    panel.add(btn1);
    panel.add(btn2);
    panel.add(btn3);
    
    add(BorderLayout.CENTER, panel);
    add(BorderLayout.SOUTH, jlOutput);
    
    btn1.addActionListener(this);
    btn2.addActionListener(this);
    btn3.addActionListener(this);
    
    setBounds(300, 200, 600, 180);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  
  @Override
  public void actionPerformed(ActionEvent ae) {
    if (ae.getSource() == btn1) {
      String name = JOptionPane.showInputDialog("이름을 입력하세요.", "홍길동");
      jlOutput.setText(name+"님 안녕하세요.");
    }
    if (ae.getSource() == btn2 ) {
      JOptionPane.showMessageDialog(this, "오늘은 금요일입니다.","요일안내",
       JOptionPane.INFORMATION_MESSAGE);
    }
    if (ae.getSource() == btn3) {
      int flag = JOptionPane.showConfirmDialog(this, "점심 맛있게 드셨어요?");
      switch (flag) {
      case JOptionPane.OK_OPTION:
        JOptionPane.showMessageDialog(this, "행복한 오후 되세요!", "행복한 오후",
         JOptionPane.PLAIN_MESSAGE);
        break;
      case JOptionPane.NO_OPTION:
        String menu = JOptionPane.showInputDialog("어떤 점심 메뉴였어요?");
        if(menu != null)
          JOptionPane.showMessageDialog(this, menu+"이(가) 다 그렇죠 뭐!");
        break;
      case JOptionPane.CANCEL_OPTION:
        JOptionPane.showMessageDialog(this, "하기싫으냐?");
        break;
      }
    }
  }

  public static void main(String[] args) {
    new UseJOptionPane();
  }
}
```

---

### JScrollPane

* **Scrollbar를 가지지 않은 컴포넌트에 Scrollbar를 추가하는 일을 함**
* JTextArea, JList, JTable의 객체는 Scrollbar를 가지지 않는다.

```java
// 1. Component 생성
JTextArea jta = new JTextArea();

// 2. JScrollPane을 생성, Component를 has-a관계로 설정
JScrollPane jsp = new JScrollPane(jta);

// 3. 배치, JTextArea를 배치하는게 아니라 JScrollPane객체를 배치한다.
add(jsp);
```

```java
public class UseScrollPane extends JFrame {
  public UseScrollPane() {
    super("스크롤 바가 없는 객체");
    
    JTextArea jta = new JTextArea();
    // JTextArea내 작성한 글이 J.T.A의 끝에 도달하면 줄  변경
    jta.setLineWrap(true);
    // 줄이 변경되면 단어를 보호하면서 줄을  변경.(한글은 안됨)
    jta.setWrapStyleWord(true);
    
    // JTextArea에 ScrollBar 설정
    // 1. JScrollPane 생성
    JScrollPane jsp = new JScrollPane(jta);
    
    // 2. 배치
    add(BorderLayout.CENTER, jsp);

    
    setBounds(100, 100, 300, 400);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  
  public static void main(String[] args) {
    new UseScrollPane();
  }
}
```

![10](/md/legacy-assets/java/24/10.webp)

* setLineWrap이 적용된 JTextArea

![11](/md/legacy-assets/java/24/11.webp)

* setWrapStyleWor가 적용된 JTextArea

![12](/md/legacy-assets/java/24/12.webp)

---

### JList

* **MVC Pattern이 적용된 컴포넌트**
  * **View : JList**
  * **Model : DefaultListModel - 데이터 **관리**
  * **Event : ListSelectionListener**
    * AWT list처럼 itemListener가 아님
    * AWT의 리스트는 View + Model
  * **Swing은 View와 Model이 분리되어 있다.**
* List는 기본적으로 스크롤바가 없음

![13](/md/legacy-assets/java/24/13.webp)

```java
// JList 생성 - Model을 사용하지 않고 생성
JList jl = new JList();

// Model 생성 후 JList 생성
// List 생성 시 모델을 has-a 관계로 생성
DefaultListModel dlm = new DefaultListModel();
JList jl = new JList(dlm);

// 데이터 추가
dlm.addElement(값);
dlm.add(인덱스, 값);

// 크기
dlm.size();

// 값얻기
dlm.get(인덱스);

// 값삭제
dlm.remove(인덱스);
dlm.removeElement(내용값);

// 선택한 Item의 인덱스
jl.getSelectedIndex();

// 선택한 Item의 값
jl.getSelectedValue();
```

---

### JList 예제

* 입력 버튼을 클릭하면 InputDialog가 뜨도록 구현, 받은 입력값은 JList에 추가
* 리스트를 아이템 클릭하면 JLabel에 선택한 아이템의 값 출력, 출력 후 리스트 아이템은 삭제 

![14](/md/legacy-assets/java/24/14.webp)

```java
/**
* MVC Pattern을 기반으로 한 Component의 사용
*
* @author owner
*/
public class UseJList extends JFrame implements ActionListener,  MouseListener {
  private JList<String> jl; // View
  private DefaultListModel<String> dlm; // Model
  private JLabel jlOutput;
  private JButton jb;

  public UseJList() {
    super("JList 사용");

    dlm = new DefaultListModel<String>();
    dlm.addElement("Java SE");
    dlm.addElement("Oracle");
    dlm.addElement("JDBC");
    dlm.addElement("HTML");
    dlm.addElement("JavaScript");
    dlm.addElement("CSS");

    jl = new JList<String>(dlm);
    // ScrollBar가 없는 JList에게 ScrollBar 설정
    JScrollPane jsp = new JScrollPane(jl);

    jlOutput = new JLabel("출력");
    jlOutput.setBorder(new TitledBorder("선택아이템"));

    jb = new JButton("입력");


    jb.addActionListener(this);
    jl.addMouseListener(this);


    add(BorderLayout.NORTH, jb);
    // 컴포넌트를 가진 스크롤바 객체를 배치
    add(BorderLayout.CENTER, jsp);
    add(BorderLayout.SOUTH, jlOutput);
    setBounds(100, 100, 300, 300);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    String lang =  JOptionPane.showInputDialog("컴퓨터개발관련언어");

    // null에서 isEmpty메소드를 호출하게 되므로 순서가  바뀌면 에러발생
    if (lang != null && !lang.isEmpty()) {
      dlm.addElement(lang);
    }
  }

  // JList Click 이벤트 처리를 위해 MouseInterface를 Override해서 사용했음
  @Override
  public void mouseClicked(MouseEvent e) {
    int idx = jl.getSelectedIndex();
    String value = dlm.get(idx);
    jlOutput.setText(value);
    dlm.removeElementAt(idx);
  }
  @Override
  public void mousePressed(MouseEvent e) {}
  @Override
  public void mouseReleased(MouseEvent e) {}
  @Override
  public void mouseEntered(MouseEvent e) {}
  @Override
  public void mouseExited(MouseEvent e) {}

  public static void main(String[] args) {
    new UseJList();
  }
}
```

![15](/md/legacy-assets/java/24/15.webp)
