Mod Tanpa Kepala Java

1. Gambaran keseluruhan

Kadang-kadang, kita perlu bekerja dengan aplikasi berasaskan grafik di Java tanpa paparan, papan kekunci, atau tetikus sebenarnya, katakanlah, di pelayan atau wadah.

Dalam tutorial ringkas ini, kita akan belajar tentang mod tanpa kepala Java untuk menangani senario ini. Kami juga akan melihat apa yang dapat kami lakukan dalam mod tanpa kepala dan apa yang tidak dapat kami lakukan.

2. Menyiapkan Mod Tanpa Kepala

Ada banyak cara untuk kita mengatur mod tanpa kepala di Java secara eksplisit:

  • Tetapkan secara sistematik sifat sistem java.awt.headless to true
  • Menggunakan argumen baris perintah: java -Djava.awt.headless = true
  • Menambah -Djava.awt.headless = true kepada JAVA_OPTS variabel persekitaran dalam skrip permulaan server

Sekiranya persekitaran sebenarnya tidak berkepala, JVM akan menyedarinya secara tidak langsung. Namun, akan ada perbezaan yang halus dalam beberapa senario. Kita akan melihatnya sebentar lagi.

3. Contoh Komponen UI dalam Mod Tanpa Kepala

Kes penggunaan khas komponen UI yang berjalan dalam lingkungan tanpa kepala boleh menjadi aplikasi penukar gambar. Walaupun memerlukan data grafik untuk pemprosesan gambar, paparan tidak begitu diperlukan. Aplikasi ini dapat dijalankan di server dan menukar fail yang disimpan atau dikirim melalui jaringan ke mesin lain untuk dipamerkan.

Mari lihat ini dalam tindakan.

Pertama, kita akan menghidupkan mod tanpa kepala secara terprogram dalam kelas JUnit :

@Before public void setUpHeadlessMode() { System.setProperty("java.awt.headless", "true"); } 

Untuk memastikannya disiapkan dengan betul, kita dapat menggunakan java.awt.GraphicsEnvironment # isHeadless :

@Test public void whenSetUpSuccessful_thenHeadlessIsTrue() { assertThat(GraphicsEnvironment.isHeadless()).isTrue(); } 

Kita harus ingat bahawa ujian di atas akan berjaya dalam persekitaran tanpa kepala walaupun mod tersebut tidak dihidupkan secara eksplisit.

Sekarang mari kita lihat penukar gambar mudah kami:

@Test public void whenHeadlessMode_thenImagesWork() { boolean result = false; try (InputStream inStream = HeadlessModeUnitTest.class.getResourceAsStream(IN_FILE); FileOutputStream outStream = new FileOutputStream(OUT_FILE)) { BufferedImage inputImage = ImageIO.read(inStream); result = ImageIO.write(inputImage, FORMAT, outStream); } assertThat(result).isTrue(); }

Dalam contoh seterusnya, kita dapat melihat bahawa maklumat semua fon, termasuk metrik fon, juga tersedia untuk kita:

@Test public void whenHeadless_thenFontsWork() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String fonts[] = ge.getAvailableFontFamilyNames(); assertThat(fonts).isNotEmpty(); Font font = new Font(fonts[0], Font.BOLD, 14); FontMetrics fm = (new Canvas()).getFontMetrics(font); assertThat(fm.getHeight()).isGreaterThan(0); assertThat(fm.getAscent()).isGreaterThan(0); assertThat(fm.getDescent()).isGreaterThan(0); }

4. Pengecualian Tanpa Kepala

Terdapat komponen yang memerlukan peranti periferal dan tidak berfungsi dalam mod tanpa kepala. Mereka membuang HeadlessException ketika digunakan dalam persekitaran yang tidak interaktif:

Exception in thread "main" java.awt.HeadlessException at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204) at java.awt.Window.(Window.java:536) at java.awt.Frame.(Frame.java:420)

Ujian ini menegaskan bahawa menggunakan Frame dalam mod tanpa kepala sememangnya akan membuang HeadlessException :

@Test public void whenHeadlessmode_thenFrameThrowsHeadlessException() { assertThatExceptionOfType(HeadlessException.class).isThrownBy(() -> { Frame frame = new Frame(); frame.setVisible(true); frame.setSize(120, 120); }); } 

Sebagai peraturan, ingat bahawa komponen tingkat atas seperti Frame dan Button selalu memerlukan persekitaran interaktif dan akan membuang pengecualian ini. Walau bagaimanapun, ia akan dinyatakan sebagai Kesalahan yang tidak dapat dipulihkan jika mod tanpa kepala tidak ditetapkan secara eksplisit .

5. Mengabaikan Komponen Berat dalam Mod Tanpa Kepala

Pada ketika ini, kita mungkin mengajukan pertanyaan kepada diri kita sendiri - tetapi bagaimana jika kita mempunyai kod dengan komponen GUI untuk dijalankan pada kedua-dua jenis persekitaran - mesin pengeluaran yang diketuai dan pelayan analisis kod sumber tanpa kepala?

Dalam contoh di atas, kami telah melihat bahawa komponen kelas berat tidak akan berfungsi pada pelayan dan akan memberikan pengecualian.

Jadi, kita boleh menggunakan pendekatan bersyarat:

public void FlexibleApp() { if (GraphicsEnvironment.isHeadless()) { System.out.println("Hello World"); } else { JOptionPane.showMessageDialog(null, "Hello World"); } }

Dengan menggunakan corak ini, kita dapat membuat aplikasi fleksibel yang menyesuaikan perilakunya sesuai dengan lingkungan.

6. Kesimpulannya

Dengan contoh kod yang berbeza, kami melihat bagaimana dan mengapa mod tanpa kepala di java. Artikel teknikal ini memberikan senarai lengkap apa yang boleh dilakukan semasa beroperasi dalam mod tanpa kepala.

Seperti biasa, kod sumber untuk contoh di atas boleh didapati di GitHub.