Upload
loctran999
View
220
Download
0
Embed Size (px)
Citation preview
7/27/2019 c6_lap_trinh_gui_2__0795
1/57
1
Chng 6: Lp trnh GUI (tt)Chng 6: Lp trnh GUI (tt)
GVLT: Trn Anh Dng
7/27/2019 c6_lap_trinh_gui_2__0795
2/57
2
Ni dungNi dung
Gii thiu vSwing
Nhngcim ca Swing
Cc thnh phn GUI thng dng ca Swing
Menu
Hthng menu
Cc loi menu
Cc thnh phn ca menu Menubar
MenuItems
Mt slpha thng dng
7/27/2019 c6_lap_trinh_gui_2__0795
3/57
3
Gii thiu Swing (1)Gii thiu Swing (1)
AWT (Abstract Windows Toolkit)
Java 1
c gn vi platform xc nh
Thch hp vi vic pht trin cc ng dng GUI n
gin. Swing
Java 2
Khng gn vi platform cnh
Mnh, a nng, linh hot
7/27/2019 c6_lap_trinh_gui_2__0795
4/574
Gii thiu Swing (2)Gii thiu Swing (2)
L mt gi nm trong th vin JFC(JavaFoundation
Classes), gm nhiu lp (classes) v giao din
(interfaces) htrmnh mcho vic lp trnh giao din
ha trn JDK.
JFCl m
t nhm cc th
vi
n
c thi
t k
h
tr
lp trnh vin to ra cc ng dng enterprise vi Java.
Swingchl mt trong cc thvin to nnJFC.
javax.swing
7/27/2019 c6_lap_trinh_gui_2__0795
5/575
Nhng c im ca Swing (1)Nhng c im ca Swing (1)
Cm quan (Look & Feels)
Khnng vit nhng cm quan (Look & Feels) cho
mi thnh phn, thm ch thayi cm quan vo thi
im runtime.
Swing c khnng thhin nhiu L&F khc nhau vhin ti h trcc L&F bao gmMetal(mc nh),
MotifvWindows.
7/27/2019 c6_lap_trinh_gui_2__0795
6/576
Nhng c im ca Swing (2)Nhng c im ca Swing (2)
Swing s dng kin trc Model - View - Controller
(MVC).
Swing c rt nhiu nhng thnh phn mi
Table, Tree, Slider, Progress Bar, Spinner, Internal
frame v Text Cc thnh phn Swing c cc Tooltip t bn trn
chng. Bn c thty chn cc skin bn phm cho
cc thnh phn, nh ngha chng hot ng nh thno vi nhng phm nng cho.
7/27/2019 c6_lap_trinh_gui_2__0795
7/577
AWT & SwingAWT & Swing
AWT vnc htrtrong Java 2
Cc thnh phn trong thvin Swing khng ththay tt
ccc thnh phn trong thvin AWT.
Chng chthay thmt phn ca AWT nh: Label,
Button, TextFeild, Panel... Cc lp tr gip khc trong AWT nh: Graphics,
Color, Font, FontMetrics, vn khng thayi.
Cc thnh phn Swing sdng m hnh sl skin
ca AWT.
7/27/2019 c6_lap_trinh_gui_2__0795
8/578
Sphn cp javax.swingSphn cp javax.swing
7/27/2019 c6_lap_trinh_gui_2__0795
9/579
JComponentJComponent
JButton
JMenuItem
JCheckBoxMenuItem
AbstractButton
JComponent
JMenu
JRadioButtonMenuItem
JToggleButton JCheckBox
JRadioButton
JComboBox
JInternalFrame JLayeredPane
JList JMenuBar JOptionPane
JPopupMenu
JProgressBar
JPane
JFileChooser
JScrollBar JScrollPane
JSeparator
JSplitPane
JSlider
JTabbedPane
JTable
JTableHeader
JTextFieldJTextComponent
JEditorPane
J TextArea
JToolBar
JToolTip
JTree
JRootPane
JPanel
JPasswordField
JColorChooser
JLabel
7/27/2019 c6_lap_trinh_gui_2__0795
10/57
10
Swing ComponentsSwing Components
Menu BarTop-levelcontainer
Contentpane
VisibleComponents
7/27/2019 c6_lap_trinh_gui_2__0795
11/57
11
JComponentJComponent
Mt sthnh phn GUI thng dng:
JFrame, JPanel, JScrollPane
Jbutton, JLabel
JTextArea
Jcheckbox
JRadioButton
JList JComboBox
...
7/27/2019 c6_lap_trinh_gui_2__0795
12/57
12
JLabelJLabel
JLabel
JLabel (Icon img): Only Icon will be used for label.
JLabel (String str): Only text will be used for label.
JLabel (String str, Icon img, int align): Label will have
both text and icon. Alignment is specified by the alignargument and can be LEFT, RIGHT, CENTER,
LEADING or TRAILING. These are constants and are
defined inSwingConstantinterface.
l.setToolTipText(ToolTip");
l.setDisplayedMnemonic('e');
7/27/2019 c6_lap_trinh_gui_2__0795
13/57
13
JButtonJButton
JButton
JButton(), JButton(Icon icon)
JButton(String text)
JButton(String text, Icon icon)
b1.setMnemonic(KeyEvent.VK_F);
7/27/2019 c6_lap_trinh_gui_2__0795
14/57
14
JTextComponentJTextComponent
JTextComponent is the root class of all Swing text
components.
JTextField
JTextArea
JPasswordField JPasswordField p = new JPasswordField(123");
p.setEchoChar('a');
7/27/2019 c6_lap_trinh_gui_2__0795
15/57
15
JCheckBoxJCheckBox
JCheckBox class has the following constructors:
JCheckBox()
JCheckBox(Icon icon)
JCheckBox(Icon icon, boolean selected)
JCheckBox(String text)
JCheckBox(String text, boolean selected)
JCheckBox(String text, Icon icon) JCheckBox(String text, Icon icon, boolean selected)
7/27/2019 c6_lap_trinh_gui_2__0795
16/57
16
JRadioButtonJRadioButton
JRadioButton object can be created by using:
JRadioButton()
JRadioButton(Icon icon)
JRadioButton(Icon, boolean selected)
JRadioButton(String text)
JRadioButton(String text, boolean selected)
JRadioButton(String text, Icon icon) JRadioButton(String text, Icon icon, boolean selected)
7/27/2019 c6_lap_trinh_gui_2__0795
17/57
17
JListJList
JFrame f = newJFrame("My frame");
String[ ] label = {"ASM","Pascal","C\\C++","VB","Java"};
JList l = newJList(label);
l.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ScrollPane s = newScrollPane();
s.add(l);
f.getContentPane().add(s);
f.setSize(100,100);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
JFrame f = newJFrame("My frame");
String[ ] label = {"ASM","Pascal","C\\C++","VB","Java"};
JList l = newJList(label);
l.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ScrollPane s = newScrollPane();
s.add(l);
f.getContentPane().add(s);
f.setSize(100,100);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
7/27/2019 c6_lap_trinh_gui_2__0795
18/57
18
JComboBoxJComboBox
JFrame f = newJFrame("My frame");
JComboBox com = newJComboBox();
com.addItem("Item 1");
com.addItem("Item 2");
com.addItem("Item 3");
f.getContentPane().add(com);
f.getContentPane().setLayout(newFlowLayout());
f.setSize(100,100);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
JFrame f = newJFrame("My frame");
JComboBox com = newJComboBox();
com.addItem("Item 1");
com.addItem("Item 2");
com.addItem("Item 3");
f.getContentPane().add(com);
f.getContentPane().setLayout(newFlowLayout());
f.setSize(100,100);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
7/27/2019 c6_lap_trinh_gui_2__0795
19/57
19
JTabbedPaneJTabbedPane
JFrame f = newJFrame("My frame");
String[ ] label={"ASM","Pascal","C\\C++","VB","Java"};
JButton[ ] b = newJButton[label.length];
JTabbedPane p = newJTabbedPane();
for(int i=0;i
7/27/2019 c6_lap_trinh_gui_2__0795
20/57
20
JTableJTable
JFrame f = newJFrame("My frame");
String[ ][ ] dat={{"1","JCreator","Xinox","Beginer"},
{"2","jGRASP","Auburn","Medium"},{"3","NetBeans","Sun Microsystems","Expert"},
{"4","Gel","GExperts","Beginer"},
{"5","Eclipse","Eclipse","Expert"},
{"6","JBuilder","Borland","Expert"}};
String[ ] columnName = {"ID","Name","Company","Rank"};
JTable t = newJTable(dat,columnName);
JScrollPane s = newJScrollPane(t);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(s);
f.setSize(500,150);f.setVisible(true);
JFrame f = newJFrame("My frame");
String[ ][ ] dat={{"1","JCreator","Xinox","Beginer"},
{"2","jGRASP","Auburn","Medium"},{"3","NetBeans","Sun Microsystems","Expert"},
{"4","Gel","GExperts","Beginer"},
{"5","Eclipse","Eclipse","Expert"},
{"6","JBuilder","Borland","Expert"}};
String[ ] columnName = {"ID","Name","Company","Rank"};
JTable t = newJTable(dat,columnName);
JScrollPane s = newJScrollPane(t);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(s);
f.setSize(500,150);f.setVisible(true);
JT blJT bl
7/27/2019 c6_lap_trinh_gui_2__0795
21/57
21
JTableJTable
String[ ][ ] dat = {{"1","JCreator","Xinox","Beginer"},
{"2","jGRASP","Auburn","Medium"},
{"3","NetBeans","Sun Micro","Expert"},
{"4","Gel","GExperts","Beginer"},
{"5","Eclipse","Eclipse","Expert"},
{"6","JBuilder","Borland","Expert"}};
String[ ] columnName = {"ID","Name","Company","Rank"};JTable t = newJTable(dat,columnName);
JScrollPane s = newJScrollPane(t); f.add(s);
JComboBox c = newJComboBox(new String[]{"Low","High","Extremely"});
TableColumn rankColumn = t.getColumn("Rank");
rankColumn.setCellEditor(new DefaultCellEditor((c));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500,200);
f.setVisible(true);
String[ ][ ] dat = {{"1","JCreator","Xinox","Beginer"},
{"2","jGRASP","Auburn","Medium"},
{"3","NetBeans","Sun Micro","Expert"},
{"4","Gel","GExperts","Beginer"},
{"5","Eclipse","Eclipse","Expert"},
{"6","JBuilder","Borland","Expert"}};
String[ ] columnName = {"ID","Name","Company","Rank"};JTable t = newJTable(dat,columnName);
JScrollPane s = newJScrollPane(t); f.add(s);
JComboBox c = newJComboBox(new String[]{"Low","High","Extremely"});
TableColumn rankColumn = t.getColumn("Rank");
rankColumn.setCellEditor(new DefaultCellEditor((c));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500,200);
f.setVisible(true);
JTJT
7/27/2019 c6_lap_trinh_gui_2__0795
22/57
22
JTreeJTree
Windows Explorer has a tree like structure depicting files
and folders.
Windows Explorer structures can be created in Java
using JTree.
Every row in the hierarchy is termed as a node.
When the nodesare clicked
MM
7/27/2019 c6_lap_trinh_gui_2__0795
23/57
23
MenuMenu
Hthng menu(Menu System): Tp cc mc chn chc
nng cang dngc tchc ph hp.
Ngn ngJava c mttp hp cc lpi tngto
cc menu.
C hai loi menu Pull-down menu
Pop-up menu
Ch c th t cc menubar vo trong cc
Frame/JFrame, Mi Frame ch cha duy nht mt
menubar
C t t hC t t h
7/27/2019 c6_lap_trinh_gui_2__0795
24/57
24
Cu trc mt hmenuCu trc mt hmenu
MenuBar Cc Menu
Thanhphn
cch
MenuItem
Cc lp lin quan n menuCc lp lin quan n menu
7/27/2019 c6_lap_trinh_gui_2__0795
25/57
25
Cc lp lin quan n menuCc lp lin quan n menu
V dV d
7/27/2019 c6_lap_trinh_gui_2__0795
26/57
26
V dV d
MenuItem hay JMenuItem
Menu hay JMenu
MenuBar hay JMenuBar
To h thng menu (1)To h thng menu (1)
7/27/2019 c6_lap_trinh_gui_2__0795
27/57
27
To hthng menu (1)To hthng menu (1)
MenuBar/JMenuBar
MenuBar()/JMenuBar()
MenuItem
MenuItem()
MenuItem(String label)
MenuItem(String label, MenuShortcuts)
JMenuItem
Menu/JMenu
Menu()
Menu(String label)
To h thng menu (2)To h thng menu (2)
7/27/2019 c6_lap_trinh_gui_2__0795
28/57
28
To hthng menu (2)To hthng menu (2)
CheckboxMenuItem
CheckboxMenuItem( )
CheckboxMenuItem(String label)
CheckboxMenuItem(String label, boolean state)
Phm ttPhm tt MenuShortcutMenuShortcut
7/27/2019 c6_lap_trinh_gui_2__0795
29/57
29
Phm ttPhm tt MenuShortcutMenuShortcut
Shortcut Key: ThpCtrl + Phmstcng vo 1 mc
chn tng tnhkch chut vo 1 mc menu.
Lp java.awt.MenuShortcut h tr thit lp cc phm
nng.
L
pjava.awt.event.KeyEvent
nh ngha s
n cc phm
V dthit lp phm nng cho MenuItem:
MenuShortcut CtrlN = newMenuShortcut(KeyEvent.VK_N));
mnuNew.setShortcut(CtrlN);// Ctrl + N
mnuOpen.setShortcut(newMenuShortcut(KeyEvent.VK_O));
V dV d
7/27/2019 c6_lap_trinh_gui_2__0795
30/57
30
V dV d
Chng trnh minh ha cch thit lp menu cho ng
dng:
MenuDemo
MenuHotkeyDemo
Hot key?
Lp PopupMenu/JPopupMenuLp PopupMenu/JPopupMenu
7/27/2019 c6_lap_trinh_gui_2__0795
31/57
31
Lp PopupMenu/JPopupMenuLp PopupMenu/JPopupMenu
Constructor
PopupMenu()/JPopupMenu()
PopupMenu(String label)/JPopupMenu(String label)
V dV d
7/27/2019 c6_lap_trinh_gui_2__0795
32/57
32
V dV d
Chng trnh minh ha cch thit lp popup menu cho
ng dng:
Popup Menu
Jpopup Menu
JProgressBarJProgressBar
7/27/2019 c6_lap_trinh_gui_2__0795
33/57
33
JProgressBarJProgressBar
Progress BarsProgress Bars
7/27/2019 c6_lap_trinh_gui_2__0795
34/57
34
Progress BarsProgress Bars
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;public classProgressBarDemo implements ActionListener {
JFrame f;
JLabel l = newJLabel("Enter a score out of 1000");JProgressBar pbar1, pbar2;
JButton done = newJButton("Done");
JTextField tf = newJTextField(10);
public static final intMAXSCORE = 1000;
//.
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;public classProgressBarDemo implements ActionListener {
JFrame f;
JLabel l = newJLabel("Enter a score out of 1000");JProgressBar pbar1, pbar2;
JButton done = newJButton("Done");
JTextField tf = newJTextField(10);
public static final intMAXSCORE = 1000;
//.
Progress BarsProgress Bars
7/27/2019 c6_lap_trinh_gui_2__0795
35/57
35
Progress BarsProgress Bars
publicProgressBarDemo(){
f = newJFrame("Demo ProgressBar");
done.addActionListener(this);pbar1 = newJProgressBar(0, MAXSCORE);
pbar1.setStringPainted(true);
pbar1.setValue(MAXSCORE);
f.getContentPane().setLayout(new FlowLayout());f.getContentPane().add(l);
f.getContentPane().add(tf);
f.getContentPane().add(done);
f.getContentPane().add(pbar1);
f.setSize(300, 300);
f.setVisible(true);
}
publicProgressBarDemo(){
f = newJFrame("Demo ProgressBar");
done.addActionListener(this);pbar1 = newJProgressBar(0, MAXSCORE);
pbar1.setStringPainted(true);
pbar1.setValue(MAXSCORE);
f.getContentPane().setLayout(new FlowLayout());f.getContentPane().add(l);
f.getContentPane().add(tf);
f.getContentPane().add(done);
f.getContentPane().add(pbar1);
f.setSize(300, 300);
f.setVisible(true);
}
Progress BarsProgress Bars
7/27/2019 c6_lap_trinh_gui_2__0795
36/57
36
Progress BarsProgress Bars
public voidactionPerformed(ActionEvent e) {if(e.getSource().equals(done)){
String score = tf.getText();int scoreval = Integer.parseInt(score);pbar2 = newJProgressBar(0, MAXSCORE);pbar2.setValue(scoreval);
pbar2.setStringPainted(true);f.getContentPane().add(pbar2);f.validate();
}
}public static voidmain(String[] args) {
ProgressBarDemo p = newProgressBarDemo();}
}
public voidactionPerformed(ActionEvent e) {if(e.getSource().equals(done)){
String score = tf.getText();int scoreval = Integer.parseInt(score);pbar2 = newJProgressBar(0, MAXSCORE);pbar2.setValue(scoreval);
pbar2.setStringPainted(true);f.getContentPane().add(pbar2);f.validate();
}
}public static voidmain(String[] args) {
ProgressBarDemo p = newProgressBarDemo();}
}
TimerTimer
7/27/2019 c6_lap_trinh_gui_2__0795
37/57
37
ee
Creates a Timer that will notify its listeners every delay
milliseconds:
Timer(intdelay,ActionListenerlistener).
Mt sphng thc:
voidstart(); voidstop();
intgetDelay();
voidsetDelay(int);
JOptionPaneJOptionPane
7/27/2019 c6_lap_trinh_gui_2__0795
38/57
38
pp
JOptionPaneJOptionPane
7/27/2019 c6_lap_trinh_gui_2__0795
39/57
39
pp
messageType: Defines the style of the message. The
Look and Feel manager may lay out the dialog differently
depending on this value, and will often provide a defaulticon. The possible values are:
ERROR_MESSAGE
INFORMATION_MESSAGE
WARNING_MESSAGE
QUESTION_MESSAGE
PLAIN_MESSAGE
JOptionPaneJOptionPane
7/27/2019 c6_lap_trinh_gui_2__0795
40/57
40
pp
optionType: Defines the set of option buttons that appear
at the bottom of the dialog box:
DEFAULT_OPTION
YES_NO_OPTION
YES_NO_CANCEL_OPTION OK_CANCEL_OPTION
JOptionPaneJOptionPane
7/27/2019 c6_lap_trinh_gui_2__0795
41/57
41
When one of the showXxxDialog methods returns an
integer, the possible values are:
YES_OPTION
NO_OPTION
CANCEL_OPTION OK_OPTION
CLOSED_OPTION
pp
Dialog CommonDialog Common
7/27/2019 c6_lap_trinh_gui_2__0795
42/57
42
gg
JColorChooser
JFileChooser
ShowDialog()
ShowOpenDialog()
ShowSaveDialog();
JSpinnerJSpinner
7/27/2019 c6_lap_trinh_gui_2__0795
43/57
43
JSpinner has an editor that displays the values and
buttons on the right hand side to move through the
values.
SpinnerModelis used to represent a sequence of values.
SpinnerModel model =newSpinnerDateModel();
SpinnerModel model =newSpinnerNumberModel();
SpinnerModel model =newSpinnerListModel(List values);
SpinnerModel model =newSpinnerListModel(Object[] values);
JSpinner spinner1 =newJSpinner(model);
JSliderJSlider
7/27/2019 c6_lap_trinh_gui_2__0795
44/57
44
Cho php ngi sdng chn gi trnguyn trong mt
vng gi trxcnh
JSlider():Creates a horizontal slider with the range 0to 100 and an initial value of 50.
JSliderJSlider
7/27/2019 c6_lap_trinh_gui_2__0795
45/57
45
Mt sconstructors:
JSlider(int orientation): Creates a slider using the
specified orientation with the range 0 to 100 and aninitial value of 50.
JSlider(int min, int max): Creates a horizontal slider
using the specified min and max with an initial value
equal to the average of the min plus max.
JSlider(int min, int max, int value) JSlider(int orientation, int min, int max, int value):
Creates a slider with the specified orientation and the
specified minimum, maximum, and initial values.
JSliderJSlider
7/27/2019 c6_lap_trinh_gui_2__0795
46/57
46
Mt smethods:
void setMajorTickSpacing(int n):This method sets the
major tick spacing.
void setMaximum(int maximum)
void setMinimum(int minimum) void setMinorTickSpacing(int n):This method sets the
minor tick spacing.
void setOrientation(int orientation):Set the scrollbars
orientation to either VERTICAL or HORIZONTAL.
ng dng MDIng dng MDI
7/27/2019 c6_lap_trinh_gui_2__0795
47/57
47
JDesktopPane
A container used to create a multiple-documentinterface.
You create JInternalFrame objects and add them to
the JDesktopPane.
Lp ColorLp Color
7/27/2019 c6_lap_trinh_gui_2__0795
48/57
48
Thit lp mu cho cc thnh phn GUI bng cch s
dung lp java.awt.Color.
Cc mu c to t3 mu cbn l red, green, blue gi l hmu RGB (RGB model).
Color c = new Color(r, g, b);
V d:
Color c = new Color(228, 100, 255);
Sdng cc phng thc tng ng thit lp mu
background v foreground cho cc thnh phn.
Lp FontLp Font
7/27/2019 c6_lap_trinh_gui_2__0795
49/57
49
Thit lp Font cho cc thnh phn
Font myFont = Font(name, style, size);
V d:
Font font1 = new Font(Arial", Font.BOLD, 16);
Font font2 = new Font("Serif", Font.BOLD + Font.ITALIC,12);
GraphicsEnvironmentGraphicsEnvironment
7/27/2019 c6_lap_trinh_gui_2__0795
50/57
50
V d: Tm tt ctn font phdng
import java.awt.GraphicsEnvironment;
public classtestAllFonts {
public static voidmain(String[] args) {
GraphicsEnvironment e =
GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontnames = e.getAvailableFontFamilyNames();
for(inti = 0; i < fontnames.length; i++)
System.out.println(fontnames[i]);
}
}
Lp FontMetricsLp FontMetrics
7/27/2019 c6_lap_trinh_gui_2__0795
51/57
51
Lp FontMetricsLp FontMetrics
7/27/2019 c6_lap_trinh_gui_2__0795
52/57
52
Mt sphng thc thng dng
public int getAscent()
public int getDescent()
public int getLeading()
public int getHeight() public int stringWidth(String str)
V d: Hin thchui Welcome to Javacanh gia trong
frame, vi font v kch thc c xc nh trc.
Lp Graphics (1)Lp Graphics (1)
7/27/2019 c6_lap_trinh_gui_2__0795
53/57
53
drawLine(x1, y1, x2, y2);
drawRect(x, y, w, h);
fillRect(x, y, w, h);
drawRoundRect(x, y, w, h, aw, ah);
fillRoundRect(x, y, w, h, aw, ah);
Lp Graphics (2)Lp Graphics (2)
7/27/2019 c6_lap_trinh_gui_2__0795
54/57
54
drawOval(x, y, w, h);
fillOval(x, y, w, h);
drawArc(x, y, w, h, angle1, angle2);
fillArc(x, y, w, h, angle1, angle2);
Lp Graphics (3)Lp Graphics (3)
7/27/2019 c6_lap_trinh_gui_2__0795
55/57
55
Va gic
int[] x = {40, 70, 60, 45, 20};
int[] y = {20, 40, 80, 45, 60};
g.drawPolygon(x, y, x.length);
g.fillPolygon(x, y, x.length);
Bi tpBi tp
7/27/2019 c6_lap_trinh_gui_2__0795
56/57
56
Tm hiu thvin javax.swing
Tm hiu cc phng thc trong lp Graphics
Xy dng dng dng vng cong hnh sin
Xy dng ng dng vng h
Hi & pHi & p
7/27/2019 c6_lap_trinh_gui_2__0795
57/57
57