Java Swing에서 set (Preferred | Maximum | Minimum) Size 메서드를 사용하지 않아야합니까?
여러 번 다음 방법의 사용을 제안한 것에 대해 비판을 받았습니다.
- setPreferredSize
- setMinimumSize
- setMaximumSize
에 Swing
구성 요소. 표시된 구성 요소 간의 비율을 정의하려는 경우 사용에 대한 대안이 없습니다. 나는 이것을 들었다 :
레이아웃의 대답은 항상 동일합니다. 적절한 LayoutManager를 사용하십시오.
웹을 조금 검색했지만 주제에 대한 포괄적 인 분석을 찾지 못했습니다. 그래서 다음과 같은 질문이 있습니다.
- 그 방법의 사용을 완전히 피해야합니까?
- 이 방법은 이유 때문에 정의되었습니다. 언제 사용해야합니까? 어떤 맥락에서? 어떤 목적으로?
- 이러한 방법을 사용하면 어떤 부정적인 결과가 발생합니까? (화면 해상도가 다른 시스템간에 이식성을 추가하는 것만 생각할 수 있습니다).
- LayoutManager가 원하는 모든 레이아웃 요구를 정확하게 충족시킬 수 있다고 생각하지 않습니다. 레이아웃의 작은 변형마다 새로운 LayoutManager를 구현해야합니까?
- 4에 대한 대답이 "예"이면, 유지 보수가 어려워지는 LayoutManager 클래스가 확산되지 않습니까?
- Component의 자식들 사이에 비율을 정의해야하는 상황에서 (예를 들어, child1은 공간의 10 %, child2 40 %, child3 50 %를 사용해야 함), 사용자 정의 LayoutManager를 구현하지 않고도 달성 할 수 있습니까?
-
그 방법의 사용을 완전히 피해야합니까?
응용 프로그램 코드의 경우 예
-
이 방법은 이유 때문에 정의되었습니다. 언제 사용해야합니까? 어떤 맥락에서? 어떤 목적으로?
나는 개인적으로 그것을 API 디자인 사고라고 생각합니다. 어린이 크기에 대한 특별한 아이디어를 가진 복합 구성 요소에 의해 약간 강제됩니다. 사용자 정의 LayoutManager로 요구 사항을 구현 했어야했기 때문에 "약간"입니다.
-
이러한 방법을 사용하면 어떤 부정적인 결과가 발생합니까? (화면 해상도가 다른 시스템간에 이식성을 추가하는 것만 생각할 수 있습니다.)
일부 (불완전하고 불행하게도 SwingLabs를 java.net으로 마이그레이션하여 링크가 끊어짐) 기술적 이유는 예를 들어 규칙 (hehe) 또는 내 답변에 대한 의견에서 찾은 @bendicott 링크에 언급되어 있습니다. 사회적으로, 코드를 유지해야하며 깨진 레이아웃을 추적해야하는 불행한 동료에게 수많은 작업을합니다.
-
LayoutManager가 원하는 모든 레이아웃 요구를 정확하게 충족시킬 수 있다고 생각하지 않습니다. 레이아웃의 작은 변형마다 새로운 LayoutManager를 구현해야합니까?
예, "모든 레이아웃 요구"에 대한 아주 좋은 근사치를 충족 할 수있을만큼 강력한 LayoutManager가 있습니다. 큰 세 가지는 JGoodies FormLayout, MigLayout, DesignGridLayout입니다. 실제로 실제로 고도로 전문화 된 환경을 제외하고는 LayoutManager를 작성하는 경우가 거의 없습니다.
-
4에 대한 대답이 "예"이면, 유지 보수가 어려워지는 LayoutManager 클래스가 확산되지 않습니까?
(4의 대답은 "아니오"입니다.)
-
구성 요소의 자식 (예 : 자식 1은 공간의 10 %, 자식 2 40 %, 자식 3 50 %를 사용해야 함) 사이의 비율을 정의 해야하는 상황에서 사용자 정의 LayoutManager를 구현하지 않고도 달성 할 수 있습니까?
모든 Big-Three는 GridBag조차도 할 수 없습니다.
몇 가지 휴리스틱 :
여기 에 표시된대로 고유 한 구성 요소를 만들 때와 같이
set[Preferred|Maximum|Minimum]Size()
재정의하려는 경우 사용하지 마십시오 .get[Preferred|Maximum|Minimum]Size()
여기 및 아래에 표시된대로
set[Preferred|Maximum|Minimum]Size()
구성 요소의 신중하게 재정의 된 구성 요소에 의존 할 수있는 경우 사용하지 마십시오 .getPreferred|Maximum|Minimum]Size
아래 및 여기에 표시된대로
set[Preferred|Maximum|Minimum]Size()
사후validate()
형상 을 도출 하는 데 사용 하십시오 .예를 들어 구성 요소에 원하는 크기가없는 경우
JDesktopPane
컨테이너의 크기를 조정해야 할 수도 있지만 이러한 선택은 임의적입니다. 의견은 의도를 명확히하는 데 도움이 될 수 있습니다.이 주석 에서 언급 한 것처럼 파생 된 크기를 얻기 위해 많은 구성 요소를 반복해야하는 경우 대체 또는 사용자 정의 레이아웃을 고려하십시오 .
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* @see https://stackoverflow.com/questions/7229226
* @see https://stackoverflow.com/questions/7228843
*/
public class DesignTest {
private List<JTextField> list = new ArrayList<JTextField>();
private JPanel panel = new JPanel();
private JScrollPane sp = new JScrollPane(panel);
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
DesignTest id = new DesignTest();
id.create("My Project");
}
});
}
private void addField(String name) {
JTextField jtf = new JTextField(16);
panel.add(new JLabel(name, JLabel.LEFT));
panel.add(jtf);
list.add(jtf);
}
private void create(String strProjectName) {
panel.setLayout(new GridLayout(0, 1));
addField("First Name:");
addField("Last Name:");
addField("Address:");
addField("City:");
addField("Zip Code:");
addField("Phone:");
addField("Email Id:");
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addPropertyChangeListener("permanentFocusOwner",
new FocusDrivenScroller(panel));
// Show half the fields
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.validate();
Dimension d = sp.getPreferredSize();
d.setSize(d.width, d.height / 2);
sp.setPreferredSize(d);
JInternalFrame internaFrame = new JInternalFrame();
internaFrame.add(sp);
internaFrame.pack();
internaFrame.setVisible(true);
JDesktopPane desktopPane = new JDesktopPane();
desktopPane.add(internaFrame);
JFrame frmtest = new JFrame();
frmtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmtest.add(desktopPane);
frmtest.pack();
// User's preference should be read from java.util.prefs.Preferences
frmtest.setSize(400, 300);
frmtest.setLocationRelativeTo(null);
frmtest.setVisible(true);
list.get(0).requestFocusInWindow();
}
private static class FocusDrivenScroller implements PropertyChangeListener {
private JComponent parent;
public FocusDrivenScroller(JComponent parent) {
this.parent = parent;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
Component focused = (Component) evt.getNewValue();
if (focused != null
&& SwingUtilities.isDescendingFrom(focused, parent)) {
parent.scrollRectToVisible(focused.getBounds());
}
}
}
}
그 방법의 사용을 완전히 피해야합니까?
아니요, 이러한 메소드를 호출하거나 재정의하는 것이 허용되지 않는다는 공식적인 증거는 없습니다. 실제로 오라클은 이러한 방법이 크기 힌트를 제공하는 데 사용된다고 말합니다 ( http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment) .
사용자 지정 구성 요소 인스턴스에서 메서드를 호출하지 않고 Swing 구성 요소를 확장 할 때 재정의 될 수도 있습니다 (Swing의 모범 사례 ).
구성 요소의 크기를 어떻게 지정하더라도 구성 요소의 컨테이너는 요청 된 구성 요소의 크기를 고려한 레이아웃 관리자를 사용해야합니다.
이 방법은 이유 때문에 정의되었습니다. 언제 사용해야합니까? 어떤 맥락에서? 어떤 목적으로?
구성 요소가 잘 배치되도록 컨테이너 레이아웃 관리자에 사용자 정의 크기 힌트를 제공해야하는 경우
이러한 방법을 사용하면 어떤 부정적인 결과가 발생합니까? (화면 해상도가 다른 시스템 사이에서만 이식성을 추가한다고 생각할 수 있습니다).
많은 레이아웃 관리자는 구성 요소의 요청 된 최대 크기에주의를 기울이지 않습니다. 그러나,
BoxLayout
및SpringLayout
않습니다. 또한GroupLayout
구성 요소를 건드리지 않고 최소, 기본 또는 최대 크기를 명시 적으로 설정할 수 있습니다.구성 요소의 정확한 크기를 설정해야합니다. 각 Swing 구성 요소는 사용하는 글꼴과 모양과 느낌에 따라 선호하는 크기가 다릅니다. 따라서 설정된 크기가 있으면 다른 시스템에서 다양한 UI 모양 을 만들 수 있습니다.
때로는
GridBagLayout
컨테이너 크기가 원하는 크기보다 작 으면 텍스트 필드에 문제가 발생할 수 있으며 최소 크기가 사용되어 텍스트 필드가 상당히 줄어 듭니다.JFrame
작업을getMinimumSize()
호출 할 때만 재정의를 시행하지 않습니다.setMinimumSize(..)
LayoutManager가 원하는 모든 레이아웃 요구를 정확하게 충족시킬 수 있다고 생각하지 않습니다. 레이아웃의 작은 변형마다 새로운 LayoutManager를 구현해야합니까?
구현하면 예를 사용하는 것을 의미합니다. LayoutManger
모든 것을 다룰 수있는 것은 아니며 각각 LayoutManager
장단점이 있으므로 최종 레이아웃을 만들기 위해 함께 사용할 수 있습니다.
참고:
이 여기에 좋은 답변이 많이 있지만 나는 이유에 대한 자세한 조금을 추가 할 왜 당신이 일반적으로 이러한 피해야한다 (질문 단지 중복 항목에 다시 와서) :
몇 가지 예외를 제외하고, 이러한 방법을 사용하는 경우 특정 모양과 느낌 (및 시스템 별 설정 (예 : 선호하는 데스크탑 글꼴 등)으로보기에 적합하도록 GUI를 미세 조정할 수 있습니다. 방법 자체는 본질적으로 악한 것이 아니지만 사용하는 일반적인 이유는 다음 과 같습니다 . 레이아웃에서 픽셀 위치 및 크기 조정을 시작하자마자 다른 플랫폼에서 GUI가 깨질 위험이 있습니다 (최소한 나빠 보일 수 있습니다).
이에 대한 예로, 응용 프로그램의 기본 모양과 느낌을 변경해보십시오. 플랫폼에서 사용 가능한 옵션만으로도 결과가 얼마나 나빠질 수 있는지에 놀랄 수 있습니다.
따라서 모든 플랫폼에서 GUI를 기능적이고 멋지게 유지하기 위해 (Java의 주요 이점 중 하나는 플랫폼 간이라는 점을 기억하십시오) 레이아웃 관리자 등에 의존하여 자동으로 크기를 조정해야합니다. 특정 개발 환경 외부에서 올바르게 렌더링되도록 구성 요소
그러나 이러한 방법이 정당화되는 상황을 확실히 생각할 수 있습니다. 다시 말하지만, 그들은 본질적으로 악하지는 않지만 일반적으로 잠재적 GUI 문제를 나타내는 큰 적기입니다. 합병증을 사용하는 경우 합병증이 발생할 가능성이 높은지 항상 확인하고 문제에 대해 다른 모양과 느낌에 독립적 인 해결책이 있는지 항상 시도하고 생각하십시오. 방법이 필요하지 않습니다.
그건 그렇고, 표준 레이아웃 관리자에 좌절감을 느끼면FormLayout
무료로 제공되는 오픈 소스 타사가 많이 있습니다 (예 : JGoodies ' 또는) MigLayout
. 일부 GUI 빌더도 내장되어 타사 레이아웃 매니저에 대한 지원 - 이클립스의 WindowBuilder GUI 편집기, 예를 들어,에 대한 지원과 함께 제공 FormLayout
하고 MigLayout
.
Java Swing에서 레이아웃에 문제가있는 경우 FormLayout
Karsten Lentzsch의 Forms 프리웨어 라이브러리의 일부로 자유롭게 제공 되는 JGoodies를 여기에서 강력하게 추천 할 수 있습니다 .
이 인기있는 레이아웃 관리자는 매우 유연하여 매우 세련된 Java UI를 개발할 수 있습니다.
Karsten의 문서는 여기 에서 찾을 수 있고 Eclipse의 일부 좋은 문서 는 여기 에서 찾을 수 있습니다 .
이러한 방법은 대부분의 사람들이 잘 이해하지 못합니다. 이러한 방법을 절대 무시해서는 안됩니다. 이러한 방법을 준수하는 경우 레이아웃 관리자가 결정합니다. 이 페이지에는 어떤 레이아웃 관리자가 어떤 방법을 사용하는지 보여주는 표가 있습니다.
http://thebadprogrammer.com/swing-layout-manager-sizing/
8 년 이상 Swing 코드를 작성해 왔으며 JDK에 포함 된 레이아웃 관리자는 항상 내 요구에 부응했습니다. 레이아웃을 달성하기 위해 타사 레이아웃 관리자가 필요하지 않았습니다.
레이아웃 관리자가 필요할 때까지 이러한 방법으로 힌트를 제공해서는 안된다고 말할 것입니다. 크기 조정 힌트를 제공하지 않고 레이아웃을 수행 한 다음 (예 : 레이아웃 관리자가 작업을 수행하도록) 필요한 경우 사소한 수정을 할 수 있습니다.
구성 요소의 자식 (자식 1은 공간의 10 %, 자식 2 40 %, 자식 3 50 %를 사용해야 함) 사이의 비율을 정의 해야하는 상황에서 사용자 정의 레이아웃 관리자를 구현하지 않고도 달성 할 수 있습니까?
아마 GridBagLayout
당신의 요구를 만족시킬 것입니다. 게다가 웹에는 수많은 레이아웃 관리자가 있으며 요구 사항에 맞는 레이아웃 관리자가 있습니다.
나는 그것이 받아 들인 대답과 다른 것을보고 있습니다.
1) 그 방법의 사용을 완전히 피해야합니까?
절대 피하십시오! 레이아웃 관리자에게 컴포넌트의 크기 제약을 표현할 수 있습니다. 레이아웃 관리자를 사용하지 않고 시각적 레이아웃을 직접 관리하려고하면 사용하지 않을 수 있습니다.
불행히도 Swing에는 합리적인 기본 크기가 제공되지 않습니다. 그러나 구성 요소의 크기를 설정하는 대신 자신의 구성 요소를 합리적인 기본값으로 내림차순으로 만드는 것이 좋습니다. (이 경우 하위 클래스에서 setXXX를 호출합니다.) 또는 동일한 효과를 위해 getXXX 메소드를 대체 할 수 있습니다.
2) 방법은 이유 때문에 정의되었습니다. 언제 사용해야합니까? 어떤 맥락에서? 어떤 목적으로?
항상. 구성 요소를 작성할 때 해당 구성 요소의 사용에 따라 실제 최소 / 기본 / 최대 크기를 설정하십시오. 예를 들어 영국과 같은 국가 기호를 입력 할 수있는 JTextField가있는 경우 기본 크기는 두 문자 (현재 글꼴 등)에 맞도록 넓어야하지만 더 커질 수는 없습니다. 결국 국가 기호는 두 문자입니다. 반대로, 예를 들어 고객 이름을 입력하기위한 JTextField가있는 경우 20 자에 대한 픽셀 크기와 같은 크기를 선호하지만 레이아웃 크기를 조정하면 더 커질 수 있으므로 최대 크기를 더 많이 설정하십시오. 동시에 0px 너비의 JTextField를 갖는 것은 의미가 없으므로 현실적인 최소 크기를 설정하십시오 (픽셀 크기는 2 자라고 말하십시오).
3) 이러한 방법을 사용하면 어떤 부정적인 결과가 발생합니까?
(화면 해상도가 다른 시스템간에 이식성을 추가하는 것만 생각할 수 있습니다).
부정적인 결과는 없습니다. 레이아웃 관리자를위한 힌트입니다.
4) LayoutManager가 원하는 모든 레이아웃 요구를 정확하게 충족시킬 수 있다고 생각하지 않습니다.
레이아웃의 작은 변형마다 새로운 LayoutManager를 구현해야합니까?
아뇨. 일반적인 접근 방식은 가로 및 세로 레이아웃과 같은 다른 기본 레이아웃 관리자를 계단식으로 배열하는 것입니다.
예를 들어 아래 레이아웃 :
<pre>
+--------------+--------+
| ###JTABLE### | [Add] |
| ...data... |[Remove]|
| ...data... | |
| ...data... | |
+--------------+--------+
</pre>
두 부분이 있습니다. 왼쪽과 오른쪽 부분은 가로 레이아웃입니다. 오른쪽 부분은 가로 레이아웃에 추가 된 JPanel이며이 JPanel에는 단추를 세로로 배치하는 세로 레이아웃이 있습니다.
물론 이것은 실제 레이아웃으로 까다로워 질 수 있습니다. 따라서 MigLayout과 같은 그리드 기반 레이아웃 관리자는 심각한 것을 개발하려는 경우 훨씬 좋습니다.
5) 4에 대한 대답이 "예"이면 LayoutManager 클래스가 확산되어 유지 관리가 어려워지지 않습니까?
매우 특별한 것이 필요하지 않으면 레이아웃 관리자를 개발하지 않아야합니다.
6) 비율을 정의 해야하는 상황에서 ...
구성 요소의 하위 (예 : child1은 공간의 10 %, child2 40 %, child3 50 %를 사용해야 함) 사이에 사용자 정의 LayoutManager를 구현하지 않고도 달성 할 수 있습니까?
기본적으로 원하는 크기를 설정 한 후에는 백분율로 아무것도하지 않을 수 있습니다. 단순히 백분율이 의미가 없기 때문에 (예를 들어, JTextField가 창 크기의 10 %를 갖는 것은 의미가 없습니다. JTextField가 0px 너비가되도록 창을 축소하거나, JTextField가 두 개의 디스플레이에 걸쳐 있도록 창을 확장 할 수 있기 때문에) 다중 디스플레이 설정).
그러나 백분율을 사용하여 GUI의 더 큰 빌딩 블록 (예 : 패널)의 크기를 제어 할 수 있습니다.
JSplitPane을 사용하여 두면의 비율을 미리 설정할 수 있습니다. 또는 MigLayout을 사용하여 백분율, 픽셀 및 기타 단위로 이러한 제약 조건을 설정할 수 있습니다.
그 방법의 사용을 완전히 피해야합니까? 나는 그들을 "피해야한다"라고 말하지 않을 것입니다. 당신이 필요하다고 생각한다면, 당신은 아마 뭔가 잘못하고 있다고 말하고 싶습니다. 구성 요소 크기는 상황에 따라 결정됩니다. 예를 들어, 텍스트 구성 요소 크기는 선택한 글꼴과 결합하여 지정한 행과 열 수에 따라 결정됩니다. 단추와 레이블 크기는 그래픽을 설정 한 경우 그래픽 크기이거나 설정 한 텍스트를 표시하는 데 필요한 공간이됩니다. 각 구성 요소의 크기는 자연스럽고 레이아웃 관리자는 크기를 지정하지 않고도 모든 구성 요소를 배치 할 수 있습니다. 주요 예외는 JScrollPane입니다. JScrollPane에는 크기에 관계없이 크기가 있습니다. 그것들을 위해, 나는 때때로 전화 setSize()
하고, 그 크기가 전화를해서 초기 창 크기를 결정하게 할 것입니다JFrame.pack()
. 일반적으로 창 크기가 JScrollPane 크기를 결정하도록합니다. 사용자는 창의 크기를 결정할 것입니다. 많은 레이아웃 관리자는 어쨌든 설정 한 크기를 무시하므로 많은 일을하지 않습니다.
이 방법은 이유 때문에 정의되었습니다. 언제 사용해야합니까? 어떤 맥락에서? 어떤 목적으로? 레이아웃 관리자에게 힌트를 제공하기 위해 추가되었다고 생각합니다. 레이아웃 관리자가 새롭고 사람들이 완전히 신뢰하지 않았기 때문에 역사적인 이유로 작성되었을 수 있습니다. 나는 새로운 패러다임을 배우고 싶지 않기 때문에 레이아웃 관리자를 피하고 모든 것을 수동으로 배치 한 소수의 개발자를 알고 있습니다. 끔찍한 생각입니다.
이러한 방법을 사용하면 어떤 부정적인 결과가 발생합니까? (화면 해상도가 다른 시스템간에 이식성을 추가하는 것만 생각할 수 있습니다). 그것들은 효과가 없으며, 객체가 압착되지 않거나 자연스럽지 않은 크기로 늘어나면서 잘못된 레이아웃을 생성합니다. 그리고 레이아웃이 부서지기 쉽습니다. 창 크기를 변경하면 레이아웃이 깨져서 잘못된 위치에 놓이는 경우가 있습니다.
LayoutManager가 원하는 모든 레이아웃 요구를 정확하게 충족시킬 수 있다고 생각하지 않습니다. 레이아웃의 작은 변형마다 새로운 LayoutManager를 구현해야합니까? 새로운 LayoutManager를 "구현"해서는 안됩니다. 기존 인스턴스를 인스턴스화해야합니다. 하나의 창에서 여러 레이아웃 관리자를 자주 사용합니다. 각 JPanel에는 자체 레이아웃 관리자가 있습니다. 일부 사람들은 유지 관리가 어렵 기 때문에 중첩 된 레이아웃을 사용합니다. 내가 그것을 사용할 때, 나는 각자가 무엇을하는지 더 쉽게 볼 수 있도록 각각의 고유 한 생성 방법을 제공합니다. 그러나 나는 결코 레이아웃 관리자를 "구현"하지 않습니다. 나는 단지 그들을 인스턴스화합니다.
4에 대한 대답이 "예"이면, 유지 보수가 어려워지는 LayoutManager 클래스가 확산되지 않습니까? 레이아웃의 약간의 변형을 위해 새로운 레이아웃 관리자 클래스를 구현하는 경우 잘못 사용하고 있습니다. 새로운 레이아웃 관리자를 구현하는 경우 무언가 잘못되었을 수 있습니다. LayoutManager 클래스를 확장 한 유일한 시점은 확대 / 축소 슬라이더를 JScrollPane에 추가하는 것이 었습니다.
Component의 자식들 사이에 비율을 정의해야하는 상황에서 (예를 들어, child1은 공간의 10 %, child2 40 %, child3 50 %를 사용해야 함), 사용자 정의 LayoutManager를 구현하지 않고도 달성 할 수 있습니까? JSplitPane에는 각 구성 요소의 백분율을 지정하는 방법이 있습니다. 디바이더는 기본적으로 움직일 수 있지만 원하는 경우 끌 수 있습니다. 나는 그 기능을 많이 사용하지 않습니다. 일반적으로 설정된 크기를 차지하는 일부 구성 요소가 있으며 나머지 공간은 스크롤 창에 의해 차지됩니다. 스크롤 창 크기는 창 크기에 따라 조정됩니다. 두 개의 스크롤 창이 나란히 있으면 JSplitPane에 배치하고 사용자가 창을 확장 및 축소 할 때 각각에 주어진 새 공간의 백분율을 지정할 수 있습니다.
'Programing' 카테고리의 다른 글
버튼과 링크에서 Firefox의 점선을 제거하는 방법은 무엇입니까? (0) | 2020.02.15 |
---|---|
명시 적 약속 건설 반 패턴은 무엇이며 어떻게 방지합니까? (0) | 2020.02.15 |
int argc, char * argv []은 무슨 뜻인가요? (0) | 2020.02.15 |
이미지가 변경된 후 도커 컨테이너를 업그레이드하는 방법 (0) | 2020.02.15 |
쉘 스크립트에서 줄 바꿈이없는 'echo' (0) | 2020.02.15 |