Процесът на разработване на проста GUI програма в Java. Създаване на Java GUI Създаване на Java GUI приложение

Графичният интерфейс в Java е преминал през много трънлив път на развитие и формиране. Дълго време той беше обвинен в бавна работа, алчност за системни ресурси и ограничена функционалност.

Java AWT

Първият опит на Sun за създаване GUIимаше библиотека за java A.W.T.(Abstract Window Toolkit) - набор от инструменти за работа с различни прозоречни среди. Sun създаде Java слой, който извиква методи от библиотеки, написани на C. Методите на библиотеката AWT създават и използват графичните компоненти на операционната среда. От една страна, това е добре, тъй като програмата на Java е подобна на други програми в същата операционна система. Но когато я стартирате на различна платформа, може да има разлики в размерите на компонентите и шрифтовете, които ще развалят външния вид на програмата.

За да се осигури мултиплатформа A.W.T.интерфейсите за повикване на компоненти са унифицирани, което води до леко намалена функционалност. И наборът от компоненти се оказа доста малък. Например, в AWT няма таблици и иконите не се поддържат в бутоните. Въпреки това пакетът java.awtвключен в Java от първата версия и може да се използва за създаване на GUI.

Така че компонентите A.W.T.не върши никаква "работа". Това е просто "обвивка на Java" за контролите на това операционна системапо който работят. Всички заявки към тези компоненти се пренасочват към операционната система, която върши цялата работа.

Използвани ресурси A.W.T.опитва да се освободи автоматично. Това леко усложнява архитектурата и се отразява на производителността. Писането на нещо сериозно с помощта на AWT ще бъде донякъде трудно. Сега се използва само за аплети.

Основни концепции на SWING

След A.W.T. Sun разработи библиотека с графични компоненти Люлка, написана изцяло на Java. 2D се използва за изобразяване, което носи със себе си няколко предимства наведнъж. Наборът от стандартни компоненти далеч надхвърля AWT по разнообразие и функционалност. Swing улеснява създаването на нови компоненти чрез наследяване от съществуващи и поддържа разнообразие от стилове и кожи.

Създатели на новата UI библиотека Люлкане „преоткриха колелото“ и избраха AWT като основа за тяхната библиотека. Разбира се, ние не говорихме за използването на специфични тежки AWT компоненти (представени от Button, Label и други подобни класове). Само леките компоненти осигуряват необходимата степен на гъвкавост и управляемост. Диаграмата на наследяване показва връзката между AWT и Swing.

Най-важната разлика Люлкаот AWT е, че компонентите на Swing изобщо не са свързани с операционната система и следователно са много по-стабилни и по-бързи. Такива компоненти се наричат ​​олекотени в Java и разбирането на основните принципи за това как работят ще помогне много, за да обясни как работи Swing.

Люлеещи се контейнери от най-високо ниво

За да създадете графичен интерфейс на приложение, трябва да използвате специални компоненти на библиотеката Swing, наречени контейнери от най-високо ниво. Те са прозорци на операционната система, които хостват компоненти на потребителския интерфейс. Контейнерите от най-високо ниво включват прозорците JFrame и JWindow, диалоговия прозорец JDialog и аплета JApplet (който не е прозорец, но също е предназначен да показва интерфейс в браузъра, изпълняващ този аплет). Swing контейнерите от най-високо ниво са тежки компоненти и са изключение от общото правило. Всички останали компоненти на Swing са леки.

просто Люлкапример за интерфейс на прозореца jFrame.

Импортиране на java.awt.Dimension; импортиране на javax.swing.JFrame; импортиране на javax.swing.JLabel; публичен клас JFrameTest ( public static void createGUI() ( JFrame frame = new JFrame("Test frame"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel label = new JLabel("Test label"); frame.getContentPane(). add(label); frame.setPreferredSize(new Dimension(200, 100)); frame.pack(); frame.setVisible(true); ) public static void main(String args) ( JFrame.setDefaultLookAndFeelDecorated(true); javax. swing.SwingUtilities.invokeLater(new Runnable() ( public void run() ( createGUI(); ) )); ) )

Конструктор JFrame()без параметри създава празен прозорец. Конструктор JFrame (заглавие на низ)създава празен прозорец със заглавие заглавие. Да създам най-простата програмас празен прозорец трябва да се използват следните методи:

  • setSize(int width, int height) - определяне на размера на прозореца;
  • setDefaultCloseOperation(int операция) - дефиниране на действие при прекратяване на програмата;
  • setVisible(boolean visible) - прави прозореца видим.

Ако не определите размера на прозореца, тогава той ще има нулева височина, независимо от това какво има в него. Размерите на прозореца включват не само "работната" зона, но и границите и заглавната лента.

Методът setDefaultCloseOperation дефинира действието, което трябва да се предприеме при "излизане от програмата". За да направите това, предайте константата EXIT_ON_CLOSE, описана в класа JFrame, като параметър на операцията.

По подразбиране прозорецът е създаден невидим. За показване на прозореца на екрана се извиква методът setVisible с параметър true. Ако го извикате с параметъра false, прозорецът ще стане невидим.

GUI java swingпример за създаване на прозорец jFrameпоказано на следващата фигура.

За свързване на библиотеката Люлкаприложението трябва да импортира библиотеката javax.swing.

Всеки път, когато се създава контейнер от най-високо ниво, било то нормален прозорец, диалогов прозорец или аплет, конструкторът на контейнера създава Основен панел JRootPane. Swing контейнерите от най-високо ниво гарантират, че другите компоненти не могат да „обхождат“ извън JRootPane.

Root Pale JRootPaneдобавя свойство "дълбочина" към контейнерите, предоставяйки възможност не само за поставяне на компоненти един над друг, но също така, ако е необходимо, да ги разменяте, да увеличавате или намалявате дълбочината на компонентите. Тази функция е необходима при създаване на приложение с множество документи. Люлка, чиито прозорци представляват леки компоненти, подредени един върху друг, както и падащи (контекстни) менюта и подсказки.

Следващата фигура ясно показва структурата на основния панел JRootPane.

Основен панел JRootPaneе контейнер, който наследява от базовия клас Swing JComponent. В този контейнер специален мениджър на оформлението, внедрен във вътрешния клас RootPaneLayout, отговаря за оформлението на компонентите. Този мениджър на оформлението е отговорен за това, че всички съставни части на основния панел са поставени както трябва: панелът със слоеве заема цялото пространство на прозореца; неговият FRAME_CONTENT_LAYER съдържа лентата с менюта и панела със съдържание, а над всичко това е прозрачен панел.

Всички компоненти на основния панел JRootPaneмогат да бъдат получени или променени. Има набор от методи за получаване/задаване за това. Програмно JRootPaneможе да се получи с помощта на метода getRootPane().

В допълнение към контейнерите от най-високо ниво, основният панел се използва във вътрешни прозорци на JInternalFrame, създадени в приложения с множество документи и разположени на "десктоп" JDesktopPane. Това ви позволява да забравите, че тези прозорци са обикновени леки компоненти и да работите с тях, сякаш са истински контейнери от най-високо ниво.

Многослоен панел JLayeredPane

В основата на основния панел (контейнер) лежи така нареченият слоест панел JLayeredPane A, който заема цялото налично пространство в контейнера. Именно в този панел се намират всички останали части на основния панел, включително всички компоненти на потребителския интерфейс.

JLayeredPaneизползва се за добавяне на свойство за дълбочина към контейнера. Тоест многослойният панел ви позволява да организирате трето измерение в контейнера, по протежение на което са разположени слоевете (слоевете) на компонента. В нормален контейнер местоположението на компонент се определя от правоъгълник, който показва каква част от контейнера заема компонентът. Когато добавяте компонент към многослоен панел, трябва да посочите не само правоъгълника, зает от компонента, но и слоя, в който ще бъде разположен. Слой в многослоен панел се определя от цяло число. Колкото по-голямо е числото, определящо слоя, толкова по-висок е слоят.

Първият компонент, добавен към контейнера, е по-висок от компонентите, добавени по-късно. Най-често разработчикът не се занимава с позициите на компонентите. Когато добавяте компоненти, тяхната позиция се променя автоматично. Слоестият панел обаче ви позволява да променяте позицията на компонентите динамично, след като бъдат добавени към контейнера.

Възможностите на многослойния панел се използват широко от някои компоненти Люлка. Те са особено важни за приложения с множество документи, подсказки и менюта. Мултидокумент Люлкаприложенията използват специален контейнер JDesktopPane("десктоп"), наследен от JLayeredPane A, който държи вътрешни Swing прозорци. Най-важните функции на многодокументно приложение - позициониране на "активния" прозорец над другите, минимизиране на прозорци, плъзгане - се осигуряват от механизмите на многослойния панел. Основното предимство на използването на многослоен панел за подсказки и менюта е тяхната скорост. Вместо да създавате нов тежък прозорец за всяка подсказка или меню, разположен над компонента, в който е поискано подсказката или менюто, Люлкасъздава бърз лек компонент. Този компонент се поставя в достатъчно висок слой на многослойния панел отгоре в стека на всички други компоненти и се използва за показване на подсказка или меню.

Многослойният панел ви позволява да организирате неограничен брой слоеве. Структура JLayeredPaneвключва няколко стандартни слоя, които се използват от всички компоненти на Swing, което гарантира, че всички механизми на многослойния панел работят правилно. Стандартните слоеве JLayeredPane са показани на следващата фигура.

Слоят по подразбиране се използва за хостване на всички нормални компоненти, които се добавят към контейнера. Този слой съдържа вътрешните прозорци на многодокументни приложения.

Слоят Palette е проектиран да хоства прозорци с набор от инструменти, които обикновено припокриват останалата част от интерфейса. Панелът JDesktopPane ви позволява да създавате такива прозорци, което ги поставя на този слой.

Модалният слой е предназначен да хоства леки модални диалогови прозорци. Такива диалогови прозорци обаче все още не са внедрени, така че този слой в момента не се използва в Swing.

Най-често използваният слой за изскачащи менюта и подсказки.

Най-горният слой. Предназначен за операции с плъзгане и пускане ( Дръпни и пусни drop), които трябва да се виждат ясно в интерфейса на програмата.

Малък пример за JLayeredPane с многослоен панел показва как да добавяте компоненти към различни слоеве и как слоевете се подреждат един върху друг:

Импортиране на javax.swing.*; импортиране на java.awt.*; // клас за рисуване на два типа фигури с текст class Figure extends JComponent ( private static final long serialVersionUID = 1L; private Color color; private int type; private String text; // параметри: цвят и тип фигура Figure(Color color, int тип, текст на низ) ( this.color = цвят; this.type = тип; this.text = текст; setOpaque(false); ) public void paintComponent(Graphics g) ( // начертайте фигурата g.setColor(color); превключвател (тип) (случай 0: g.fillOval(0, 0, 90, 90); прекъсване; случай 1: g.fillRect(0, 0, 130, 80); прекъсване; ) g.setColor(Color.yellow) ; g. drawString(text, 10, 35); ) ) публичен клас JLayeredPaneTest разширява JFrame ( private static final long serialVersionUID = 1L; public JLayeredPaneTest() ( // създаване на прозорец super("Пример LayeredTest"); // изход при прозорец е затворен setDefaultCloseOperation( EXIT_ON_CLOSE); // дефиниране на слоест панел JLayeredPane lp = getLayeredPane(); // създаване на три форми Фигура figure1 = нова Фигура(Color.red , 0, "Figure po кученце"); Фигура figure2 = нова фигура (Color.blue, 0, "Фигура 1"); Фигура figure3 = нова фигура (Color.cyan, 1, "Фигура 2"); // определяме местоположението на фигурите в прозореца figure1.setBounds(10, 40, 120, 120); figure2.setBounds(60, 120, 160, 180); фигура3.setBounds(90, 55, 250, 180); // добавяне на форми към различни слоеве lp.add(figure1, JLayeredPane.POPUP_LAYER); lp.add(фигура2, JLayeredPane.PALETTE_LAYER); lp.add(фигура3, JLayeredPane.PALETTE_LAYER); // промяна на позицията на една от фигурите lp.setPosition(figure3, 0); // определяне на размера и отваряне на прозореца setSize(280, 250); setVisible(true); ) public static void main(String args) ( JFrame.setDefaultLookAndFeelDecorated(true); new JLayeredPaneTest(); ) )

Примерът създава малък прозорец jFrameи множество компоненти на фигури се добавят към панела със слоеве. За да получите слоест панел във всеки Swing контейнер от най-високо ниво, просто извикайте метода getLayeredPane().

Помощният клас Figure наследява свойствата на базовия клас JComponent и ви позволява да рисувате два типа форми (кръгове и правоъгълници) с различни цветове. Параметрите за рисуване на фигури се задават в конструктора на класа.

При дефиниране на интерфейс се създават три фигури с различни цветове (два кръга и правоъгълник). Кръгът се поставя в слоя POPUP_LAYER, а правоъгълниците се поставят в слоя PALETTE_LAYER. При поставяне на компоненти се посочват техните абсолютни екранни координати, тъй като обичайните мениджъри на местоположението не работят в многопластов панел.

Накрая позицията на един от правоъгълниците се променя така, че да е първият в слоя, въпреки че първоначално е добавен вторият. Когато стартирате приложението, ще видите, че многослойният панел работи и спретнато подрежда компонентите според техните слоеве и позиции.

В конвенционалните приложения слоестият панел рядко се използва директно, при което той изпълнява функциите си невидимо. Понякога обаче помага да се създадат невероятни ефекти и необичайни интерфейси, позволявайки например да се постави анимация или видео върху обикновени компоненти, без да се изискват нечовешки усилия и трикове от разработчика.

ContentPane

ContentPane е следващата част от основния панел и се използва за хостване на компонентите на потребителския интерфейс на програмата. ContentPaneзаема по-голямата част от пространството на наслоения панел (с изключение на пространството, заето от лентата с менюта). За да се предотврати панелът със съдържание да покрива компоненти, които впоследствие се добавят към прозореца, панелът със слоеве го поставя на специален много нисък слой, наречен FRAME_CONTENT_LAYER, номериран -30000.

Можете да получите достъп до панела със съдържание, като използвате getContentPane()Клас JFrame. Използвайки метода add(Component component), можете да добавите всяка контрола към него. Сменете ContentPaneвсеки друг панел от тип JPanel, можете да използвате метода setContentPane()

Пример за добавяне на бутон към панела със съдържание:

JButton newButton = нов JButton(); getContentPane().add(newButton);

В резултат на това получаваме прозорец с бутон. Бутонът заема цялата налична площ на прозореца. Този ефект не е полезен във всички програми, така че трябва да използвате различни начини за подреждане на елементи на панела.

Панелът със съдържание може да бъде напълно заменен. Помислете за следното Люлкапример за панел със съдържание ContentPane.

Импортиране на javax.swing.*; публичен клас ContentPaneReplace разширява JFrame ( private static final long serialVersionUID = 1L; public ContentPaneReplace() ( super("Test ContentPane"); setDefaultCloseOperation(EXIT_ON_CLOSE); // Създаване на панел с два бутона JPanel contents = new JPanel(); contents. add (new JButton("Family")); contents.add(new JButton("School")); // Замяна на панела със съдържание setContentPane(contents); // Определяне на размера на прозореца setSize(200, 100); // Отваряне на прозореца setVisible (true); ) public static void main(String args) ( JFrame.setDefaultLookAndFeelDecorated(true); new ContentPaneAdd(); ) )

Примерът създава малък прозорец и панел с два бутона, който след това setContentPane()замества панела със съдържание на прозореца. По този начин беше използвана замяна вместо по-просто добавяне - извикване на метода add (). Интерфейсът на прозореца е показан на следната екранна снимка.

Панел със съдържание ContentPaneсамо по себе си не е нищо особено. Просто трябва да запомните, че компонентите се добавят към него.

Прозрачен JOptionPane

Прозрачен панел JOptionPaneпоставен като основен панел над всички елементи на наслоения панел. Поставянето на JOptionPane се управлява от основния панел, който поставя прозрачния панел над наслоения панел, така че да покрива напълно цялата област на прозореца, включително зоната, заета от лентата с менюта.

JOptionPaneсе използва рядко в приложения, така че по подразбиране основният панел го прави невидим, което намалява натоварването на системата за чертане. Имайте предвид, че ако направите прозрачен панел видим, трябва да се уверите, че той е прозрачен (свойството му opaque е false), защото в противен случай той ще покрие всички останали елементи на основния панел и останалата част от интерфейса ще бъде невидима .

В какви случаи може да се използва прозрачен панел? JOptionPane? Може да се използва за дефиниране на функции на приложение, чието внедряване от нулата би изисквало значителни усилия. Прозрачният панел може да бъде адаптиран за автоматизирано тестване на потребителския интерфейс. Събитията, синтезирани в него, ви позволяват да проследявате междинни резултати от отстраняване на грешки. Понякога този подход е много по-ефективен от ръчното тестване.

Прозрачен панел JOptionPaneможе да се използва за създаване на фантастични анимации, които "плават" върху всички компоненти, включително лентата с менюта, или за улавяне на събития, ако някои от тях трябва да бъдат обработени, преди да бъдат изпратени към основния потребителски интерфейс.

Пример за използване на прозрачен Swing JOptionPane:

// Използване прозрачен панел JOptionPane import java.awt.Dimension; импортиране на java.awt.Font; импортиране на java.awt.event.WindowEvent; импортиране на java.awt.event.WindowListener; импортиране на javax.swing.JDialog; импортиране на javax.swing.JFrame; импортиране на javax.swing.JLabel; импортиране на javax.swing.JOptionPane; импортиране на javax.swing.UIManager; публичен клас JOptionPaneTest разширява JFrame ( private static final long serialVersionUID = 1L; public static final Font FONT = new Font("Verdana", Font.PLAIN, 11); public static void createGUI() ( JFrame frame = new JFrame("Test JOptionPane" "); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new WindowListener() ( public void windowActivated(WindowEvent event) () public void windowClosed(WindowEvent event) () public void windowDeactivated(WindowEvent event) () public void windowDeiconified(WindowEvent event) () public void windowIconified(WindowEvent event) () public void windowOpened(WindowEvent event) () public void windowClosing(WindowEvent event) ( Object options = ( "Да", "Не!"); int rc = JOptionPane.showOptionDialog(event.getWindow(), "Затваряне на прозорец?", "Потвърждаване", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, опции, опции; (false);System.exit(0); ) ) )); JLabel етикет = нов JLabel("Използване на прозрачен панел при затваряне на прозорец"); frame.getContentPane().add(етикет); frame.setPreferredSize(ново измерение(350, 80)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); ) public static void main(String args) ( javax.swing.SwingUtilities.invokeLater(new Runnable() ( public void run() ( UIManager.put("Button.font", FONT); UIManager.put("Label.font" ", FONT); JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); createGUI(); ) )); ) )

Ако методът setDefaultCloseOperation се предава като константа JFrame.EXIT_ON_CLOSE, тогава когато прозорецът се затвори, приложението ще спре да работи. В примера на този метод се предава константа JFrame.DO_NOTHING_ON_CLOSEтака че нищо да не се случва, когато прозорецът е затворен. Излизането от приложението в примера се извършва от JFrame слушателя WindowListener в метода прозорец Затваряне. Когато прозорецът е затворен, методът windowClosing се извиква с параметър на събитие WindowEvent, който в прозрачен Swing JOptionPane отваря диалогов прозорец за потвърждение.

Следната екранна снимка показва два прозореца на приложението. Горен основен прозорец. Затварянето на този прозорец отваря долния диалогов прозорец за потвърждение на намерението.

JMenuBar Лента с менюта

Една от важните характеристики на използването на главния панел на JRootPane в Swing е необходимостта да поставите лента с менюта в прозореца. JMenuBar. Сериозно приложение не може да бъде изградено без някакво меню за достъп до функциите на програмата. Библиотеката Swing предоставя отлични възможности за създаване на удобни JMenuBars, които също са леки компоненти.

Лента с менюта JMenuBarпоставен в многослоен панел в специален слой FRAME_CONTENT_LAYER и заема малко пространство в горната част на прозореца. Дължината на лентата с менюта е равна на размера на прозореца. Ширината на лентата с менюта зависи от компонентите, които съдържа.

Основният панел гарантира, че панелът със съдържание и лентата с менюта JMenuBarне се припокриваше. Ако лентата с менюта не е необходима, тогава основният панел използва цялото пространство, за да побере панела със съдържание.

Примери за суинг

Изходните кодове на примерите, разгледани в текста на страницата, могат да бъдат изтеглени.

В тази кратка статия искам да опиша процеса на създаване на малка програма, която поддържа GUI на езика Java. Предполага се, че читателят е запознат с основите на езика. Java.

И така, какви инструменти са ни необходими:

  • Java Virtual Machine (OpenJDK или Oracle JDK)
  • Intellij IDEA (или друга IDE за Java)

След монтажа необходимия софтуер, отворено IntelliJ ИДЕЯи създайте нов проект: Файл -> Нов проект...

Нарекох проекта guiBase. Както можете да видите на екранната снимка, папката srcне съдържа нищо, така че създаваме в него нашия основен клас, съдържащ функцията основен.

Публичен клас Main ( public static void main(String args) ( System.out.println("Hello, Govzalla!"); ) )

Вижте съдържанието на основния клас по-горе. Вече можем да създадем проект ( проект за изграждане ) и го стартирайте ( Бягай ). Долу в терминала на вашия IDEще видите съобщение Здравей, Говзала!. Но както сами разбрахте - не поддържа GUI.

На този етап вече имаме работеща програма, но без GUI поддръжка. И сега в същата папка srcсъздавам GUI форма: Ново -> GUI форма

Отворете създадения GUI формуляр, щракнете върху jPanelи задайте неговия идентификатор в полето име на полето, Попитах панел.

След това плъзнете и пуснете върху формуляра от дясната страна JTextField, JPasswordFieldи jButton:

Остава да добавим кода и да свържем нашата форма с него. Когато добавихме формата главен прозорец, класът беше създаден автоматично главен прозорец, този клас е класът на генерираната форма, т.е. този клас ще обслужва всички събития от дадената форма.

Въпреки че нашият прозоречен клас съдържа необходимите елементи, дори сега той няма нищо общо с GUI, така че нека го разширим с jFrameи наследява цялата основна и необходима функционалност на GUI .

В момента имаме формата главен прозореци класа главен прозорецудължен с jFrame. Сега трябва да дефинираме всички добавени GUI елементи като съдържание на клас главен прозорец this.getContentPane().add(панел); След това съдържанието на файла MainWindow.java ще бъде променено, както следва:

Импортиране на javax.swing.*; публичен клас MainWindow разширява JFrame ( private JTextField textField1; private JPasswordField passwordField1; private JButton button1; private JPanel panel; public MainWindow() ( this.getContentPane().add(panel); ) )

Ако се опитате да стартирате кода, ще видите отново същото съобщение „Здравей, Говзала!“. Въпросът е, че създадохме клас и формата към него, но не създадохме екземпляр на този клас.

Време е да променим файла Main.java и да добавим кода за създаване на нашия GUI там:

Импортиране на java.awt.*; public class Main ( public static void main(String args) ( // Създайте екземпляр на класа MainWindow MainWindow mainWindow = new MainWindow(); // Пакетирайте всички елементи от нашата форма mainWindow.pack(); // Преоразмерете прозореца mainWindow.setSize( new Dimension(200, 200)); // Показване на създадения прозорец mainWindow. setVisible(true); ) )

Изпълнение на кода

Като щракнете върху бутона ще забележите, че програмата не реагира по никакъв начин. Работата е там, че все още не сме добавили слушателя ( Слушател) за събития ( събития) на бутона.

слушател на събития ( слушател на събития) jButtonтрябва да е реализация на адаптер ActionListener, така че добавете следния код към тялото на класа главен прозорец:

Частният клас MyButtonListener имплементира ActionListener ( @Override public void actionPerformed(ActionEvent actionEvent) ( ) )

Метод действиеИзвършено() ще обработва всички събития на бутона button1, но първо трябва да кажете на button1 какъв клас ще обработва, така че добавете следния код към конструктора на клас MainWIndow: this.button1.addActionListener(new MyButtonListener()); За да не е безсмислен нашия манипулатор, добавете следния код към метода действиеИзвършено():

@Override public void actionPerformed(ActionEvent actionEvent) ( if (textField1.getText().equals(passwordField1.getText())) ( JOptionPane.showMessageDialog(null, "Успех"); ) else ( JOptionPane.showMessageDialog(null, "Failure ");)))

Сега програмата ще реагира правилно на събития, не на всички събития, разбира се. Например, ако се опитате да деактивирате програмата, като щракнете върху кръста, прозорецът ще изчезне, но програмата ще продължи да работи, т.к. не е добавен манипулатор на събития в главния прозорец.

Описание на презентацията Създаване на графичен интерфейс в Java Graphic библиотеки чрез слайдове

Графични библиотеки на Java Java има следните пакети за създаване на графични интерфейси: Abstract Windows Toolkit (AWT) - идва с JDK, всеки AWT компонент има свой собствен визуален компонент (peer) за конкретна ОС, преносимостта се осигурява от пакета java. авт. връстник; наборът от графични компоненти е ограничен; външният вид зависи от операционната система. Standard Widget Toolkit (SWT) - доставя се отделно за конкретна операционна система, включена в средата на Eclipce, взаимодейства с операционната система чрез партньорски интерфейси, за разлика от AWT, гамата от компоненти е разширена. Swing - идва с JDK, разширява AWT класовете, не зависи от компонентите на OS peer. Java 3 D - триизмерна графика.

Тежки и олекотени компоненти Тежки компоненти – Рендирани от операционната система – Повечето AWT компоненти Леки (ligntweight) компоненти – Рендирани от Java код – Всички компоненти на Swing с изключение на прозорци от най-високо ниво (прозорец на приложение) Тежките компоненти винаги се изчертават върху олекотените

Архитектура на модел-изглед-контролер (MVC) Моделът на проектиране на MVC разделя данните на приложението, потребителския интерфейс и контролната логика на три отделни компонента – модел, изглед и контролер – така че всеки компонент да може да се модифицира независимо. Моделът (моделът) съхранява данните на компонента и улеснява, без да се позовава на самия компонент, промяната или получаването на тези данни. Преглед (изглед) показва данни на екрана за представяне на потребителя. Контролерът определя как изгледът и данните на модела трябва да реагират в отговор на действията на потребителя.

Предимства на MVC Можете да прикачите множество изгледи към един и същ модел, без да засягате изпълнението на модела. Например, някои данни могат да бъдат представени едновременно в електронна таблица, стълбовидна диаграма и кръгова диаграма. Без да засягате изпълнението на изгледите, можете да промените реакциите към действията на потребителя (щракване върху бутон, въвеждане на данни), за това е достатъчно да използвате различен контролер. Редица разработчици се специализират само в една от областите: или разработване на графичен интерфейс, или разработване на бизнес логика. Следователно е възможно да се гарантира, че програмистите, участващи в разработването на бизнес логика (модел), няма да знаят кое представяне изобщо ще се използва.

Взаимодействия между модел, изглед и контролер Класически модел Тясна връзка между контролер и модел и контролер и изглед. Изглед (изглед) е свързан с един контролер и всеки контролер с един изглед. Изгледът и контролерът имат директна връзка към модела.

MVC пример публичен клас Модел ( private int int. Array = (1, 2, 3, 4, 5); public String get. String. Array() ( return "int. Array=" + Arrays. to. String(int. Array); ) public void set.Int.Array(int index, int value) ( ​​​​this.int.Array = value; ) ) public class Controller ( Model model = new Model(); изглед изглед= newView(); Controller()( update. View(); ) void set. Масив. Стойност(int индекс, int стойност) ( ​​model. set. Int. Array(index, value); update. View(); ) void update. View() ( view. show. Array(model. get. String. Array()); ) ) public class View ( public void show. Array(String array. String)( System. out. println("View"); System.out.println(array.String); System.out.println(); ) ) публичен клас Потребител ( public statc void main(String args) ( Controller controller = new Controller(); controller.set.Array.Value( четиринадесет);))

Моделът Swing опростява внедряването. Моделът не знае с кой представител на потребителския интерфейс си сътрудничи или кой компонент използва, задава външния вид и усещането за всички компоненти на библиотеката, комуникира с модела само чрез класа на компонента. Изгледът на контролера обработва потребителски събития и рисува компонента на екрана Бутони, списъци, таблици, текстови полета...

Компоненти на интерфейса Бутон — бутон; JCheck. Кутия - отметка; jCombo. Box - падащ списък; JLabel - етикет, надпис; jList - списък; JPassword. Поле - текстово поле за скрито въвеждане; JProgress. Лента - компонент за извеждане на число в определен диапазон; JRadio. Button - превключватели, радио бутони, обикновено използвани с компонента Button. група; JSlider - компонент, който ви позволява да изберете стойност от даден диапазон; JTable - маса; jtext. Field е едноредово текстово поле; jtext. Областта е многоредово текстово поле; JTree е дърво.

Интерфейсни контейнери Части от потребителския интерфейс, съдържащи други компоненти Контейнери от най-високо ниво: Frame, JFrame - прозорец на приложението; JDialog - диалогов прозорец на приложението; jcolor. Chooser - диалог за избор на цвят; jfile. Chooser - диалог за избор на файлове и директории; файл. Диалог - диалог за избор на файлове и директории (awt компонент). Прости контейнери: JPanel - прост панел за групиране на елементи, включително вложени панели; jTool. Лента - лента с инструменти (обикновено бутони); JScroll. Pane - лента за превъртане, която ви позволява да превъртате съдържанието на дъщерен елемент; JDesktop. Панел - контейнер за създаване на виртуален работен плот или приложения, базирани на MDI (интерфейс с множество документи); JEditor. Панел, JText. Панел - контейнери за показване на сложен документ като HTML или RTF; JTabbed. Панел - контейнер за управление на отметки;

Създаване на прозорец за импортиране на java. авт. *; клас също. просто. Frame extends Frame( public statc void main(String args)( Frame fr = new Too. Simple. Frame(); fr. set. Size(400, 150); // размер на прозореца fr. set. Visible(true); / /render window) // бутонът за затваряне не работи) Swing

Прозорец с персонализирана икона за импортиране на javax. люлка. *; публичен клас Frame. Затварянето разширява JFrame ( public Frame. Closing() ( super("Window Title"); // операция при затваряне на прозореца. По подразбиране. Close. Operaton(EXIT_ON_CLOSE); // при затваряне на прозореца, изход // икона за набор от прозорци. Icon.Image(get. Toolkit(). get. Image("icon. gif")); // C: / икони / икона. png // набор от дисплеи. Size(300, 100); // прозорец размер ширина и височина set.Visible(true); // визуализира прозорец) public statc void main(String args) ( new Frame.Closing(); ) ) Swing

Стандартни диалогови прозорци Тип на диалоговия прозорец Описание NFORMATION_MESSAGE Диалоговият прозорец показва информация с общо предназначение с икона от подходящ вид WARNING_MESSAGE Диалогов прозорец показва предупредителна информация с икона от подходящ вид QUESTION_MESSAGE Диалогов прозорец за въпрос за въвеждане на информация ERROR_MESSAGE Диалогов прозорец показва информация за грешка с икона от подходящ вид PLAIN_MESSAGE Показва че диалоговият прозорец не принадлежи към нито един от горните типове. Показва се на екрана без стандартна икона. Диалоговите прозорци могат да бъдат модални или безмодни Диалоговите прозорци могат да бъдат модални (фокус върху прозореца, докато бутонът не бъде натиснат) или безмодни

Прозорците за въвеждане и съобщения импортират java. авт. *; импортиране на javax. люлка. *; public class Soluton ( public static void main(String args) ( JOpton. Pane. show. Message. Dialog(null , "Hello, World"); String s = JOpton. Pane. show. Input. Dialog("Въведете вашето име" ); ) ) Люлка

Стандартни оформления на Java 1. Оформление на граници. Оформление (полярно разположение). 2. Flow Composer. Оформление (последователно поставяне). 3. Линкер. Решетка. Оформление (оформление на маса). 4. Пружинен линкер. Оформление (относително разположение). 5. Кутия линкер. Оформление (поставяне на блокове).

Полярно оформление (оформление Border.Layout) Стойност на Border.Layout. Оформление. СЕВЕР или низът "Север" - компонентът е разположен по горната (северна) граница на прозореца и се простира до цялата му ширина. Това обикновено е мястото, където се намира лентата с инструменти. Гранична стойност. Оформление. ЮГ или низът "Юг" - компонентът е разположен по долната (южна) граница и се простира до цялата ширина на прозореца. Тази позиция е идеална за лентата на състоянието. Гранична стойност. Оформление. WEST или низът "West" - компонентът е разположен по лявата (западна) граница на прозореца и се простира до цялата му височина, но се вземат предвид размерите на северния и южния компонент (те са с приоритет). Гранична стойност. Оформление. EAST или низът "East" - компонентът се намира по дясната (източна) граница на прозореца. В противен случай местоположението му е подобно на западния компонент. Гранична стойност. Оформление. ЦЕНТЪР или линията "Център" - компонентът се поставя в центъра на прозореца, като заема максималното възможно пространство.

Пример за използване на оформлението Border. Оформление за импортиране на javax. люлка. *; импортиране на java. авт. *; публичен клас Border. Оформление. Примерът разширява JFrame ( public Border. Layout. Sample() ( super("Border. Layout. Sample"); set. Size(400, 300); set. Default. Close. Operaton(EXIT_ON_CLOSE); // получаване на панел със съдържание на клас JFrame Container c = get.Content.Pane(); // По подразбиране Swing използва мениджъра Border.Layout // добавя компоненти към панела, използвайки низови константи c.add(new JButton("North"), "North") ; c. add(new JButton("South"), "South"); // или константи от клас Border. Layout // JLabel елемент за показване на текст c. add(new JLabel("West"), Border. Layout. WEST); c. add(new JLabel("East"), Border. Layout. EAST); // ако параметърът изобщо не е зададен, компонентът ще бъде автоматично добавен към центъра c. add(new JButton(" Center")); // показване на прозорец към екран set.Visible(true); ) public statc void main(String args) ( new Border.Layout.Sample(); ) ) Swing

Последователно разположение (Поток. Оформление на оформлението) Оформлението подрежда компонентите отляво надясно, отгоре надолу (по подразбиране в Jpanels). импортиране на javax. люлка. *; импортиране на java. авт. *; публичен клас Flow. Оформление. Примерът разширява JFrame ( public Flow. Layout. Sample() ( super("Flow. Layout 1"); set. Size(400, 200); set. Default. Close. Operaton(EXIT_ON_CLOSE); // вземете панела със съдържание Container c = get.Content.Pane(); // задайте компонентите да бъдат последователни и централно подравнени c.set.Layout(new Flow.Layout(Flow.Layout.CENTER)); // добавете компонентите c.add( new JButton(" One")); c. add(new JButton("Two")); c. add(new JButton("Three")); // показване на набора от прозорци. Visible(true); ) public statc void main( String args) ( new Flow.Layout.Sample(); ) ) import java. авт. *; импортиране на javax. люлка. *; публичен клас Soluton ( public static void main(String args) ( JOpton. Pane. show. Message. Dialog(null , "Hello, World"); ) ) Swing

Оформление на таблица (Grid. Layout layout) всички компоненти имат еднакъв размер. Наличното пространство се разделя на същия брой клетки, във всяка от които се поставя компонентът; всички компоненти винаги се изтеглят на екрана, без значение колко голямо или малко е наличното пространство. импортиране на java. авт. *; импортиране на javax. люлка. *; импортиране на java. utl. *; клас Grid. Тестът разширява JFrame ( Grid. Test(String s)( super(s); Container c = get. Content. Pane(); // 4 реда 4 колони, разстояние между редовете и колоните в пиксели c. set. Layout(new Grid. Layout(4, 4, 5, 5)); String. Tokenizer st = new String. Tokenizer("7 8 9 / 4 5 6 * 1 2 3 - 0. = +"); while(st. has. More. Tokens()) c. add(new Button(st. next. Token())); set. Size(200, 200); set. Visible(true); ) public static void main(String args)( new Grid. Тест(" Grid Manager. Layout"); ) ) Swing

Табличното оформление ще даде на бутоните еднакъв размер, а последователното оформление няма да им позволи да се „замъглят“ и в същото време да ги подравнят към десния край I mport java. авт. *; импортиране на javax. люлка. *; публичен клас Command. Buttons разширява JFrame ( public Command. Buttons() ( super("Command. Buttons"); set. Size(350, 250); set. Locaton(150, 100); set. Default. Close. Operaton(EXIT_ON_CLOSE); / / създайте панел с оформление на таблица за подравняване на размерите на бутоните JPanel grid = new JPanel(new Grid. Layout(1, 2, 5, 0)); // 1 ред, 2 колони, 5px хоризонтално, 0 вертикално. // добавяне компоненти grid. add(new JButton("OK")); grid. add(new JButton("Cancel")); // поставете резултата в подравнен вдясно последователен панел JPanel flow = new JPanel( new Flow.Layout( Flow. Layout. RIGHT)); flow. add(grid); // вземете панела със съдържание Container c = get. Content. Pane(); // поставете реда с бутони в долната част на прозореца c. add(flow , Border .Layout.SOUTH); // Прозорец на дисплея set.Visible(true); ) public statc void main(String args) ( new Command.Buttons(); ) ) Swing

Оформление на кутия (Box. Layout layout) Мениджърът за оформление на кутия подрежда компоненти в контейнер в блокове: колона (по оста Y) или ивица (по оста X), докато всеки отделен компонент може да бъде подравнен в центъра, отляво или отдясно, както и отгоре или отдолу.

Пример за блоково разположение импортиране на java. авт. *; импортиране на javax. люлка. *; публичен клас Box 1 разширява JFrame ( public Box 1() ( super("Box 1 - Y"); set. Size(400, 200); set. Default. Close. Operaton(EXIT_ON_CLOSE); // вземете панела със съдържание Container c = get.Content.Pane(); // задаване на оформление на y-box Box.Layout boxy = нов Box.Layout(c, Box.Layout.Y_AXIS); c.set.Layout(boxy); // добавяне на компоненти c . add(new JButton("One")); c. add(new JButton("Two")); c. add(new JButton("Three")); // показване на набора от прозорци. Visible (true); ) statc class Box 2 разширява JFrame ( public Box 2() ( super("Box 2 - X"); // задайте размера и позицията на набора от кутии. Size(400, 200); set. Locaton(100, 100 ); set.Default.Close.Operaton(EXIT_ON_CLOSE); // получаване на панела със съдържание Container c = get.Content.Pane(); //задаване на поле x позиция (лента) Box.Layout boxx = нов Box.Layout (c , Box. Layout. X_AXIS); c. set. Layout(boxx); // добавяне на компоненти c. add(new JButton("One")); c. add(new JButton("Two")); c .add (нов JButton("Три")); // показване на прозореца на екрана. видим (вярно); ) ) public statc void main(String args) ( new Box 1(); new Box 2(); ) ) Swing 5 Този пример създава два прозореца. Единият от тях изпълнява блоково оформление по оста Y, а другият - блоково оформление по оста X.

Давидов Антон Валериевич
Студент в TSU, Русия, Толиати
Научен ръководител: Ерофеева Е.А.

Потребителският интерфейс в Java е преминал през много трънлив път на формиране и развитие. Отдавна е обвиняван, че е алчен за системни ресурси, бавна производителност и ограничена функционалност. Появата на .NET с по-бързи графични компоненти допълнително разклати позициите на Java. Но такава конкуренция само стимулира Java разработчицикъм разработването и подобряването на графичните библиотеки. И в тази статия ще видим какво се получи от това.

Инструментариум за абстрактни прозорци

Abstract Window Toolkit (съкратено AWT) беше пуснат за първи път през 1995 г. от Sun Microsystems. Това беше първият опит за създаване на GUI за Java. AWT действаше като слой, който извикваше методи от библиотеки, написани на C. И тези методи от своя страна използваха графичните компоненти на операционната система. От една страна, изградената по този начин програма изглеждаше сходна на външен вид с всички други програми на използваната операционна система, но от друга страна, една и съща програма може да изглежда напълно различно на различни операционни системи, което усложнява разработката. Освен това, в името на мултиплатформата, беше необходимо да се унифицират интерфейсите за повикване на компонентите, което доведе до донякъде съкратена функционалност. Наборът от компоненти също е доста скромен. Например, няма таблици и не могат да се поставят икони в бутоните. AWT се опитва автоматично да освободи използваните ресурси. Това се отразява на производителността и усложнява архитектурата. AWT е лесен за научаване, но писането на нещо сложно е трудно. Сега AWT се използва главно за аплети. В момента Oracle насърчава разработчиците да преминат към Swing, тъй като е по-сигурен.

Фиг.1 - Примерна програма, написана с помощта на AWT в Windows среда

След AWT, през 1998 г., Sun издава Swing. Написан е изцяло на Java и използва 2D за изобразяване. Swing има много по-голямо разнообразие от компоненти от AWT. Самите компоненти станаха много по-лесни за създаване чрез наследяване от съществуващите. Възможността за използване на различни стилове и кожи също беше въведена. Скоростта на ранните версии на Swing обаче беше доста ниска и грешките при писането на програма можеха дори да доведат до замръзване на операционната система.

Въпреки това, поради своята лекота на изучаване и наличието на голямо количество документация, Swing се превърна в най-популярния GUI в Java. Въз основа на него се появиха много разширения, като SwingX и JGoodies, които улесняват още повече създаването на визуално сложни приложения. Всички съвременни среди за програмиране на Java включват графичен редакторЛюлка. Въпреки че сега съществуват по-модерни рамки, Swing остава най-популярният.


Фиг. 2 - Примерна програма, написана с помощта на Swing

Стандартен инструментариум за джаджи

SWT беше пуснат от IBM във време, когато Swing все още беше бавен и главно за популяризиране на програмната среда Eclipse. Подобно на AWT, SWT използва OS компоненти, но различни интерфейси за оперативна съвместимост се използват за различни платформи. Следователно за всяка операционна система трябва да се достави отделна JAR библиотека. Това ви позволява да използвате по-пълно функциите, съответстващи на различни операционни системи. А липсващите компоненти бяха реализирани с помощта на 2D. SWT обаче се оказа по-труден за овладяване от Swing. Освен това програмистът трябва сам да реализира освобождаването на ресурси от приложението.

Фиг.3 - Примерна програма, написана с помощта на Swing

JavaFX беше пуснат през 2008 г. от Oracle. Позиционира се като платформа за създаване на богато интернет приложение. За рендиране се използва графичен конвейер, който значително ускорява приложението. Има голям набор от вградени компоненти. Има и отделни компоненти за начертаване на графики. Реализирана поддръжка за мултимедийно съдържание, анимация и дори мултитъч. Появата на компонентите се конфигурира с помощта на CSS стилове. В допълнение, наборът от помощни програми JavaFX включва възможността да направите собствен инсталатор за най-популярните платформи: exe или msi за Windows, deb или rpm за Linux, dmg за Mac. Уебсайтът на Oracle има подробна документация и голям брой готови примери.

По този начин, след като описахме основните характеристики и недостатъци на горните графични потребителски интерфейси, можем да решим за кои задачи те са най-подходящи. Abstract Window Toolkit е по-подходящ за създаване на аплети. Един начинаещ може да препоръча Swing с оглед на факта, че можете да намерите огромно количество документация за него в Интернет, включително на руски. JavaFX е страхотен за изграждане на богати интернет приложения.

Списък на използваните източници

    Риженко А. В. Обектно-ориентирано програмиране: Учебно-методически комплекс по дисциплината за специалност 010501 - "Приложна математика и информатика". – 2007 г.

    Khabibullin I. Sh. Java 7 (4-то изд.). - BHV-Петербург, 2012.

    Кларк Дж., Конърс Дж., Бруно Е. Дж. JavaFX: Разработване на богати интернет приложения. – Pearson Education, 2009 г.

    Northover S., Wilson M. Swt: the standard widget toolkit, volume 1. - Addison Wesley Professional, 2004.

Потребителският интерфейс в Java е преминал през много трънлив път на формиране и развитие. За дълго времетой беше обвинен в бавна работа, алчност за системни ресурси, ограничена функционалност. Появата на .NET с по-бързи графични компоненти допълнително разклати позициите на Java. Но всеки облак има сребърна подплата - цялото това движение само стимулира разработчиците на Java да разработват и подобряват графичните библиотеки. Да видим какво ще излезе от това.

Инструментариум за абстрактни прозорци

AWT беше първият опит на Sun за GUI за Java. Те поеха по лесния път и просто направиха Java слой, който извиква методи от библиотеки, написани на C. Библиотечните методи създават и използват графичните компоненти на операционната среда. От една страна, това е добре, тъй като програмата на Java е подобна на другите програми в тази операционна система. Но от друга страна, няма гаранция, че разликите в размерите на компонентите и шрифтовете няма да развалят външния вид на програмата, когато се изпълнява на различна платформа. Освен това, за да се осигури мултиплатформа, беше необходимо да се уеднаквят интерфейсите за повикване на компонентите, поради което тяхната функционалност се оказа малко съкратена. И наборът от компоненти се оказа доста малък. Например AWT няма таблици и бутоните не поддържат показване на икони.

Използваните ресурси AWT се опитва да освободи автоматично. Това леко усложнява архитектурата и се отразява на производителността. Научаването на AWT е доста лесно, но писането на нещо сложно може да бъде малко трудно. Сега се използва само за аплети.

Предимства:

  • част от JDK;
  • скорост на работа;
  • графичните компоненти са подобни на стандартните.

недостатъци:

  • използването на естествени компоненти налага ограничения върху използването на техните свойства. Някои компоненти може изобщо да не работят на „неродни“ платформи;
  • някои свойства, като икони и подсказки, изобщо не съществуват в AWT;
  • Има много малко стандартни AWT компоненти, програмистът трябва да внедри много потребителски;
  • програмата изглежда различно различни платформи(може да е крив).

заключение:

В момента AWT се използва изключително рядко - главно в стари проекти и аплети. Oracle скри уроците и силно насърчава прехода към Swing. Това е разбираемо, директният достъп до компонентите на оста може да бъде сериозна дупка в сигурността.

Люлка


Следвайки AWT, Sun разработи набор от графични компоненти, наречени Swing. Swing компонентите са написани изцяло на Java. 2D се използва за изобразяване, което носи със себе си няколко предимства наведнъж. Наборът от стандартни компоненти далеч надхвърля AWT по разнообразие и функционалност. Стана лесно да създавате нови компоненти, наследявайки съществуващи и рисувайки каквото сърцето ви желае. Стана възможна поддръжка за различни стилове и кожи. Скоростта на първите версии на Swing обаче остави много да се желае. Една неправилно написана програма може дори да закачи здраво Windows.

Независимо от това, поради своята лекота на използване, богата документация и гъвкави компоненти, Swing се превърна в може би най-популярната графична рамка в Java. На негова основа се появиха много разширения, като SwingX, JGoodies, които значително опростяват създаването на сложни потребителски интерфейси. Почти всички популярни среди за програмиране на Java включват графични редактори за Swing формуляри. Следователно няма да е трудно да разберете и започнете да използвате Swing.

Предимства:

  • част от JDK, няма нужда от инсталиране на допълнителни библиотеки;
  • има още много книги и отговори във форума за Swing. Всички проблеми, особено за начинаещи, са добре познати на Google;
  • вграден редактор на формуляри в почти всички среди за разработка;
  • има много разширения, базирани на swing като SwingX;
  • поддръжка за различни стилове (изглед и усещане).

недостатъци:

  • прозорец с много компоненти започва да се забавя;
  • работата с мениджъри на оформление може да бъде истински кошмар в сложните интерфейси.

Заключение:

Суингът е живял, Суингът е жив, Суингът ще живее. Въпреки че Oracle се опитва да популяризира JavaFX, Swing остава най-популярната Java UI рамка днес.

Стандартен инструментариум за джаджи


как
изглежда
SWT

SWT е разработен в IBM в дните, когато Swing все още беше бавен, и беше направено главно за популяризиране на програмната среда Eclipse. SWT, подобно на AWT, използва компоненти на операционната система, но има свои собствени интерфейси за взаимодействие за всяка платформа. Така че за всеки нова системаще трябва да изпратите отделна JAR библиотека с подходящата SWT версия. Това позволи по-пълно използване на съществуващите характеристики на компонентите на всяка ос. Липсващите функции и компоненти бяха внедрени с помощта на 2D, като в Swing. SWT има много привърженици, но, честно казано, не можем да не се съгласим, че всичко се оказа не толкова просто, колкото бихме искали. Начинаещият ще трябва да отдели много повече време за изучаване на SWT, отколкото за запознаване със същия Swing. Освен това SWT поставя задачата за освобождаване на ресурси на програмиста и затова той трябва да бъде особено внимателен, когато пише код, така че случайно изключение да не доведе до изтичане на памет.

Предимства:

  • използва компоненти на операционната система - скоростта е по-висока;
  • Eclipse предоставя визуален редакторформи;
  • обширна документация и много примери;
  • възможно е да се използват компоненти AWT и Swing.

недостатъци:

  • за всяка платформа е необходимо да се предостави отделна библиотека;
  • трябва постоянно да наблюдавате използването на ресурси и да ги освобождавате навреме;
  • сложна архитектура, предизвикваща мисли за самоубийство след напразни опити за внедряване на потребителски интерфейс.

Заключение:

Вижда се, че IBM са се постарали. Но се оказа много аматьорско ...

JavaFX


JavaFX може да се нарече пробив без преувеличение. За рендиране се използва графичен конвейер, който значително ускорява приложението. Наборът от вградени компоненти е обширен, има дори отделни компоненти за чертане на графики. Реализирана поддръжка за мултимедийно съдържание, много ефекти на дисплея, анимации и дори мултитъч. Външният вид на всички компоненти може лесно да се промени с помощта на CSS стилове. И най-хубавото е, че JavaFX включва набор от помощни програми, които ви позволяват да направите естествен инсталатор за най-популярните платформи: exe или msi за Windows, deb или rpm за Linux, dmg за Mac. На уебсайта на Oracle можете да намерите подробна документация и огромен брой готови примери. Това прави програмирането с JavaFX лесно и приятно.

Предимства:

  • бърза работа поради графичния конвейер;
  • много различни компоненти;
  • поддръжка на стил;
  • помощни програми за създаване на програма за инсталиране на програми;
  • приложението може да се стартира като десктоп и в браузъра като част от страницата.

недостатъци:

  • рамката все още се разработва, така че се случват сривове и някои проблеми;
  • JavaFX все още не се използва широко.

Заключение:

Добра работа, Oracle. Рамката оставя само положителни впечатления. Лесно е за разбиране, методите и интерфейсите изглеждат логични. Искам да използвам отново и отново!

Визуалните библиотеки на практика

SWT: джаджа за времето

За да демонстрираме възможностите на най-популярните графични библиотеки и основните принципи на работа с тях, ще направим няколко малки джаджи, които показват различна информация.

И нека започнем, може би, с най-популярната джаджа - показване на текущото време, за изпълнението на което ще изберем SWT.

Всяка SWT програма започва със създаването на Display обект. Той служи като вид контекст на приложение, който съдържа необходимите методи за достъп до системните ресурси и осигурява цикъл на събития. Следващата стъпка е да създадете също толкова важния обект Shell. Shell е нормален прозорец на операционната система. Display се предава на конструктора на обвивката, за да създаде прозорец от най-високо ниво.

Display display = new Display(); shell = нов Shell(дисплей, SWT.NO_TRIM);

Тъй като създаваме джаджа, не е необходимо да показваме стандартната рамка на прозореца и бутоните за управление, за това сме посочили флага NO_TRIM. За фон ще използваме картина - правоъгълник със заоблени ъгли. По принцип един SWT прозорец може да приеме всякаква форма. За да постигнем този ефект, използваме класа Region. Всичко, което е необходимо, е да добавите към този клас всички видими точки от фоновото изображение, като пропуснете прозрачните.

Качване на изображение:

Image image = ново изображение(display, "images/bg.png#26759185");

В изображения с различни формати прозрачността се задава по различни начини, така че информацията за прозрачните области също не се извлича по същия начин. Създайте фонова област и добавете всички видими точки там:

Регион регион = нов регион (); ImageData imageData = image.getImageData(); if (imageData.alphaData != null) ( Rectangle pixel = new Rectangle(0, 0, 1, 1); for (int y = 0; y< imageData.height; y++) { for (int x = 0; x < imageData.width; x++) { if (imageData.getAlpha(x, y) == 255) { pixel.x = imageData.x + x; pixel.y = imageData.y + y; region.add(pixel); } } } } else { ImageData mask = imageData.getTransparencyMask(); Rectangle pixel = new Rectangle(0, 0, 1, 1); for (int y = 0; y < mask.height; y++) { for (int x = 0; x < mask.width; x++) { if (mask.getPixel(x, y) != 0) { pixel.x = imageData.x + x; pixel.y = imageData.y + y; region.add(pixel); } } } }

Задайте формата на прозореца:

Shell.setRegion(регион);

Сега трябва да създадем слушател на събития за прозореца. Ще се интересуваме от събития за рисуване на прозорец, събития с мишката и натискания на клавиши, така че прозорецът да може да се движи по екрана.

Listener listener = new Listener() ( int startX, startY; public void handleEvent(Event e) ( if (e.type == SWT.KeyDown && e.character == SWT.ESC) ( shell.dispose(); ) if (e.type == SWT.MouseDown && e.button == 1) ( startX = e.x; startY = e.y; ) if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0 ) ( Point p = shell.toDisplay(e.x, e.y); p.x -= startX; p.y -= startY; shell.setLocation(p); ) if (e.type == SWT.Paint) ( e.gc.drawImage( изображение, imageData.x, imageData.y); ) ) );

Така че, като натиснете клавиша Esc, прозорецът ще се затвори. Когато натиснете левия бутон на мишката върху областта на прозореца, запомнете координатите на щракването. При движение на мишката с натиснат ляв бутон преместваме прозореца на екрана според движението. При събитие за преначертаване - изчертайте фоново изображение с помощта на GC графичен контекст.

Задайте слушател на съответните събития в прозореца:

Shell.addListener(SWT.KeyDown, слушател); shell.addListener(SWT.MouseDown, слушател); shell.addListener(SWT.MouseMove, слушател); shell.addListener(SWT.Paint, слушател);

Задайте размера на прозореца спрямо размера на изображението:

Shell.setSize(imageData.x + imageData.width, imageData.y + imageData.height);

Отворете прозореца и стартирайте цикъла на събитията:

Shell.open(); докато (!shell.isDisposed ()) ( ако (!display.readAndDispatch ()) display.sleep (); )

Не забравяйте да освободите използваните ресурси в края:

region.dispose(); image.dispose(); display.dispose();

Пускайки програмата на този етап, ще получим правоъгълник, който може да се мести с мишката и да се затваря с Esc.

Време е да добавите съдържание. Ще покажем текущото време под формата на икона за състояние (слънчево, дъжд, сняг ...), показания на температурата и часа на последната актуализация.

Мениджърите за оформление се използват за подреждане на графични компоненти в прозореца в желаната форма. Мениджърът на оформлението се занимава не само с подреждането на компонентите, но и с тяхното преоразмеряване, когато прозорецът се преоразмерява. Ще използваме GridLayout за нашата джаджа. Този мениджър подрежда компонентите в клетките на въображаема таблица. Създайте GridBagLayout за две колони с различни ширини на колони (фалшив флаг в конструктора), задайте го като мениджър на оформлението на прозореца:

GridLayout layout = нов GridLayout(2, false); shell.setLayout(оформление);

За изображението на състоянието използваме компонента Label. Предаваме обекта прозорец като родител. Вторият параметър е да зададете стила на компонента. За всеки компонент наборът от възможни флагове за стил е различен, те могат да бъдат намерени в документацията или директно в изходния код на компонента.

//изчертаване на изображение на състоянието Label imageLabel = нов етикет(shell, SWT.NONE); imageLabel.setLayoutData(нови GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1));

Флаговете в класа GridData означават, че етикетът ще бъде позициониран горе вляво, ще се разтяга хоризонтално и вертикално (флагове, зададени на true), когато има свободно място, и ще заема един ред и една колона от таблицата с оформление.

Не в SWT прозрачен фонкомпоненти и бял фон ще се показва зад изображението на състоянието, което, разбира се, не би било желателно. И така, нека създадем Color обект с цвета на фона на прозореца:

Цвят bgColor = нов цвят (дисплей, 0x2b, 0x2b, 0x2b);

В края на програмата този обект също трябва да бъде изчистен чрез извикване на метода dispose. Задайте цвета на фона и изображението на състоянието, което може да се зареди от файл по същия начин, както заредихме фоновото изображение в началото:

ImageLabel.setBackground(bgColor); Статус на изображението Изображение = ново изображение (дисплей, "images/1.png#26759185"); imageLabel.setImage(statusImage);

Сега нека добавим етикет с текущата температура и да го поставим в горната дясна част на прозореца:

Label temperatureLabel = new Label(shell, SWT.NONE); temperatureLabel.setLayoutData(нови GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));

Нека зададем температура:

TemperatureLabel.setText("+1 \u2103");

За да се запише температурата в Целзий, Unicode номерът на съответния знак се използва със служебните знаци \u.

Шрифтът по подразбиране за текстови етикети е твърде малък. Така че нека създадем нов, по-голям:

FontData fD = temperatureLabel.getFont().getFontData(); fD.setHeight(30); fD.setStyle(SWT.BOLD); Шрифт newFont = нов шрифт(дисплей, fD); temperatureLabel.setFont(newFont); Шрифтът, подобно на други ресурсни обекти, трябва да бъде освободен. За да направим това, използваме слушателя на събития за унищожаване на етикети:

TemperatureLabel.addDisposeListener(new DisposeListener() ( public void widgetDisposed(DisposeEvent e) (newFont.dispose(); ) ));

И накрая, нека добавим етикет, описващ метеорологичните условия:

Описание на етикета Етикет = нов етикет (обвивка, SWT.WRAP); descriptionLabel.setLayoutData(нови GridData(SWT.FILL, SWT.CENTER, true, true, 2, 1)); descriptionLabel.setText("Облачно с прояснявания, слаб дъжд"); descriptionLabel.setBackground(bgColor); descriptionLabel.setForeground(display.getSystemColor(SWT.COLOR_WHITE));

Текстът може да бъде доста дълъг, така че когато създаваме етикета, ние определяме флага WRAP, така че текстът автоматично да се раздели на няколко реда, когато няма достатъчно място. Нека центрираме компонента и го оставим да запълни цялото хоризонтално пространство. Също така уточняваме, че компонентът заема две колони от таблицата с оформление. Стартираме и получаваме прозорец от картината "Weather Widget".

Сега можете да свържете някакъв вид метеорологична услуга, да създадете таймер за автоматични актуализации - и джаджата е готова.

Swing: винаги свежи новини

В Swing ще напишем уиджет за показване на RSS емисии. Започваме, както миналия път, като създадем прозорец. Класът, който реализира стандартната функционалност на прозореца в Swing, се нарича JFrame. По подразбиране затварянето на прозорец на приложение в Swing не води до спиране на програмата, така че е по-добре да посочите как трябва да се държи прозорецът, когато е затворен:

JFrame рамка = нов JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

Таблица е най-подходяща за представяне на новини. Swing е изграден върху модела Model-View-Controller (MVC). В MVC архитектурата моделът предоставя данните, изгледът е отговорен за показването на данните (напр. текст, полета за въвеждане), а контролерът осигурява взаимодействието между модела и изгледа. Таблицата добре демонстрира този подход. За представяне на данни се използва клас, който имплементира интерфейса TableModel.

За да съхраняваме информация за налични новини, нека създадем клас FeedMessage с полета за заглавието на статията и датата на издаване:

Публичен клас FeedMessage ( публичен String title; public Date publicationDate; )

За да опростим и ускорим разработката, ние наследяваме нашия модел на данни от класа AbstractTableModel, който предлага готова реализация на почти всички методи на интерфейса TableModel.

Публичният клас RssFeedTableModel разширява AbstractTableModel (частен списък записи = нов ArrayList<>(); public void updateData(List записи) ( this.entries = записи; fireTableDataChanged(); ) public int getRowCount() ( return entries.size(); ) public int getColumnCount() ( return 2; ) public Object getValueAt(int rowIndex, int columnIndex) ( switch (columnIndex) ( case 0: return entries.get(rowIndex).title; case 1: return entries.get(rowIndex).publicationDate; ) return null; ) )

Методът fireTableDataChanged казва на изгледа, че моделът на данните е променен и трябва да бъде рендериран отново.

Създаваме таблица и променяме малко външния й вид, така че да изглежда по-скоро като джаджа. Премахваме линиите между редовете и колоните, увеличаваме височината на реда и премахваме заглавката на таблицата с имена на колони:

Таблица JTable = нова JTable(нов RssFeedTableModel()); tablesetShowGrid(false); table.setIntercellSpacing(ново измерение(0, 0)); tablesetRowHeight(30); table.setTableHeader(null);

Сега да се заемем външен видклетки. Swing ви позволява да присвоите отделни класове на изглед към различни типове данни. Класът, който наследява интерфейса TableCellRenderer, е отговорен за изобразяването на отделни клетки от таблица. По подразбиране е DefaultTableCellRenderer, което е текстов етикет.

Нека присвоим нашия клетъчен рендер на String данни. Нека променим цвета на шрифта по подразбиране и да направим цвета на фона алтернативен, за да подобрим четливостта.

Table.setDefaultRenderer(String.class, new DefaultTableCellRenderer() ( Цвят oddColor = нов цвят(0x25, 0x25, 0x25); Цвят evenColor = нов цвят(0x1a, 0x1a, 0x1a); Цвят titleColor = нов цвят(0x3a, 0xa2, 0xd7) ); public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) ( super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setBackground(row % 2 == 0 ?oddColor: evenColor); setForeground(titleColor); setFont(font); върне това; ) ));

За да може таблицата да започне да използва нашия рендър, трябва да добавим метод, който връща типа данни за всяка клетка към модела на данни:

обществен класgetColumnClass(int columnIndex) ( switch (columnIndex) ( case 0: return String.class; case 1: return Date.class; ) return Object.class; )

Може да има много новини, така че нека поставим таблицата върху лентата за превъртане и да направим лентата за превъртане невидима, така че да не разваля нашия дизайн на джаджа:

JScrollPane scrollPane = нов JScrollPane(таблица); table.setFillsViewportHeight(true); scrollPane.getVerticalScrollBar().setPreferredSize(ново измерение(0,0));

Добавяне на компонент за превъртане към главния панел на прозореца. Вторият аргумент може да бъде местоположението на компонента. По подразбиране основният панел на прозорец използва мениджъра за оформление BorderLayout, който подрежда компонентите по кардинални посоки. Нека поставим таблицата с превъртане в центъра.

Frame.getContentPane().add(scrollPane, BorderLayout.CENTER);

Както миналия път, ще премахнем стандартната рамка на прозореца. И като заглавие на прозореца ще използваме стилизиран текстов етикет, който ще поставим в горната част на прозореца.

JLabel titleLabel = нов JLabel("Xakep RSS"); Font titleFont = нов шрифт ("Arial", Font.BOLD, 20); titleLabel.setFont(titleFont); titleLabel.setHorizontalAlignment(SwingConstants.CENTER); titleLabel.setForeground(Color.WHITE); titleLabel.setPreferredSize(ново измерение(0, 40)); frame.getContentPane().add(titleLabel, BorderLayout.NORTH);

За разлика от SWT, обектите "цвят" и "шрифт" се освобождават автоматично, така че вече не е нужно да се притеснявате за изтичане на памет.

Добавяме слушатели на мишката, така че прозорецът да може да се мести по екрана.

MouseAdapter слушател = нов MouseAdapter() ( int startX; int startY; public void mousePressed(MouseEvent e) ( if (e.getButton() == MouseEvent.BUTTON1) ( startX = e.getX(); startY = e.getY( ); ) ) public void mouseDragged(MouseEvent e) ( Point currCoords = e.getLocationOnScreen(); frame.setLocation(currCoords.x - startX, currCoords.y - startY); ) ); titleLabel.addMouseListener(слушател); titleLabel.addMouseMotionListener(слушател);

Сега променете формата на прозореца на правоъгълник със заоблени ъгли. Най-добре е да направите това в слушателя на компонента, защото ако размерът на прозореца се промени, формата на прозореца ще бъде правилно преизчислена:

Frame.addComponentListener(new ComponentAdapter() ( public void componentResized(ComponentEvent e) ( frame.setShape(new RoundRectangle2D.Double(0, 0, frame.getWidth(), frame.getHeight(), 20, 20)); ) ) );

Задайте размера на прозореца, премахнете рамката и направете прозореца полупрозрачен.

Frame.setSize(520, 300); frame.setUndecorated(true); frame.setOpacity(0.85f);

Накрая отваряме прозорец в графичната нишка. SwingUtilities.invokeLater(new Runnable() ( public void run() ( frame.setVisible(true); ) ));

Остава да добавим зареждане на данни в отделна тема и ще получим такава джаджа с последните новини от любимото ви списание :).


JavaFX: Да слушаме музиката

И накрая, акцентът на сезона е JavaFX. Нека използваме неговите мултимедийни възможности и графичен компонент и да направим прост еквалайзер.

Първо, наследяваме класа widget от Application. Това е основният клас приложение в JavaFX. Приложението съдържа основните методи от жизнения цикъл на приложението. Компонентите на формуляра се създават в метода start, чийто аргумент е класът Stage. Сцената представлява прозореца на програмата. Променете стила на прозореца на ПРОЗРАЧЕН, за да премахнете рамката и бутоните. Класът Stage съдържа класа Scene, който задава размера на прозореца и цвета на фона. В Scene от своя страна предаваме класа Group, в който ще поставим дъщерни компоненти:

Public void start(Stage primaryStage) ( primaryStage.initStyle(StageStyle.TRANSPARENT); Group root = new Group(); Scene scene = new Scene(root, 400, 200, Color.TRANSPARENT); primaryStage.setScene(scene);

За да покажем еквалайзера, използваме лентова диаграма, по осите на която ще покажем честотата и звуковата мощност:

CategoryAxis xAxis = нова CategoryAxis(); NumberAxis yAxis = нова NumberAxis(0,50,10); BarChart bc = нова BarChart (xAxis,yAxis); bc.setPrefSize(400, 200); bc.setLegendVisible(false); bc.setAnimated(false); bc.setBarGap(0); bc.setCategoryGap(1); bc.setVerticalGridLinesVisible(false); bc.setHorizontalGridLinesVisible(false); xAxis.setLabel("Честота"); yAxis.setLabel("Мощност"); yAxis.setTickLabelFormatter(нов NumberAxis.DefaultFormatter(yAxis, null, "dB"));

Попълнете диаграмата с изходни данни:

XYChart.Series серия1 = нова XYChart.Series (); series1Data = нов XYChart.Data; Категории на низове = нов низ; за (int i=0; i (категории [i], 50); series1.getData().add(series1Data[i]); ) bc.getData().add(series1);

Създайте правоъгълник със заоблени ъгли, за да придадете подходящата форма на джаджата:

Правоъгълник правоъгълник = нов правоъгълник (0, 0, 400, 200); Stop stops = new Stop ( new Stop(0, new Color(0, 0, 0, 0.8)), null); LinearGradient lg2 = нов LinearGradient(0, 0, 0, 0, false, CycleMethod.NO_CYCLE, спира); rectangle.setFill(lg2); rectangle.setArcHeight(20); rectangle.setArcWidth(20);

Добавете двата компонента към групата:

Root.getChildren().addAll(правоъгълник, bc);

Задайте слушатели на мишката към групата, за да местите прозореца около екрана:

Root.setOnMousePressed(нов EventHandler () ( public void handle(MouseEvent me) ( initX = me.getScreenX() - primaryStage.getX(); initY = me.getScreenY() - primaryStage.getY(); ) )); root.setOnMouseDragged(нов EventHandler () ( public void handle(MouseEvent me) ( primaryStage.setX(me.getScreenX() - initX); primaryStage.setY(me.getScreenY() - initY); ) ));

Изтеглете песента на плеъра:

File file = new File("пусни ме от тук.mp3"); медия audioMedia = нула; audioMedia = нова медия(file.toURI().toURL().toString()); audioMediaPlayer = нов MediaPlayer(audioMedia);

Добавете слушател, който ще актуализира лентовата диаграма:

AudioMediaPlayer.setAudioSpectrumListener(нов AudioSpectrumListener() ( public void spectrumDataUpdate(двоен времеви печат, двойна продължителност, плаващи величини, плаващи фази) ( for (int i = 0; i< series1Data.length; i++) { series1Data[i].setYValue(magnitudes[i] + 60); } } });

Направете сцената видима и пуснете песента:

PrimaryStage.show(); audioMediaPlayer.play();

Стартираме приложението:

Public static void main(String args) ( launch(args); )

И се насладете на тази красота.