2013幎のJAVA + Swing。それだけの䟡倀はありたすか

HabréSwingでは奜きではありたせん。 「Swing」を怜玢するず、ニュヌトラルたたはネガティブな参照が埗られたす。 それらのいく぀かを次に瀺したす。



Swingが理想的であるふりはしたせん。 これは真実ではありたせん。 しかし、私が盎面しなければならなかった長所ず短所を説明しようずしたす。



スむングする理由



私は数幎間、断続的にSwingを䜿甚しおいたす。 䞻に倕方に。 写真をグルヌプで保護するためのビゞュアルりォヌタヌマヌクプログラムを曞いおいたす。 私は2011幎にJavaバヌゞョンを持っおいたした。Mac甚のポヌトを䜜成しおむンタヌフェむスをなめたかったのですが、プラットフォヌムごずに別々のプログラムを曞く方法がありたせんでした。



2011幎の初め、クロスプラットフォヌム開発UIラむブラリは次の状態にありたした。



圓時、JavaはMac OS Xの䞀郚であり、優れたネむティブルックアンドフィヌルを備えおおり、Windows JREの重量はわずか12メガバむトでした。 私は単玔に成功を確信しおいたした。 その結果、2か月たたは3か月の䜜業の埌、Java Swingプログラムの最初のバヌゞョンになりたした。



珟圚たでに、蚘茉されおいる問題はQMLおよびJavaFXで修正されおいたす。 したがっお、ステヌゞグラフを䜿甚する準備ができおいる堎合は、それらを詊運転しおください。



QtはDigiaの傘䞋に入りたした。 iPhoneおよびAndroidのベヌタリリヌスは、ラむブラリのさらなる開発ぞの垌望を䞎えたす。



JavaFXは、今幎2月にオヌプン゜ヌスラむブラリになりたした。 OpenJDK ずの互換性は JDK 9で蚈画されおいたす。9kaが発衚された時点では䞍明です。 8番目のバヌゞョンのリリヌスは2014幎初頭に予定されおいたす。



いいね



良いずころから始めたしょう。 突然、私もSwing-hateersにサむンアップしたず思いたすか



すべおのレンダリングはハヌドりェアアクセラレヌションです。 SwingアプリケヌションはGPUでレンダリングされるため、開発者は䜕も必芁ずしたせん。 これにより、アプリケヌションでアニメヌションが可胜になりたす。 アプリケヌションがフルスクリヌンたたは24むンチモニタヌに展開されおいる堎合を含みたす。



MVC Swingは巚倧であるず批刀されおいたす。各コンポヌネントは、ビュヌ、コントロヌラヌ、モデルで構成されおいたす。 同時に、これにより、既存のコンポヌネントに目的の機胜をすばやく远加できたす。 すべおが非垞に柔軟です。



Javaはマネヌゞコヌドです。 C ++開発者のみが「利甚可胜な」バグの可胜性を取り陀きたす。 アクセス違反のリスクは最小限に抑えられたす。 これは、他のバグがないこずを意味するものではありたせんが。 たずえば、メモリリヌク。



優れた開発環境。 Eclipse、Intellij IDEA、NetBeans-遞択は膚倧です。 どこにでもリファクタリング、コヌドのフォヌマット、オヌトコンプリヌト、単䜓テストのサポヌト、



倚くのラむブラリ。 ネむティブオブゞェクト、文字列、Webを操䜜するLayoutManagers-すべおをリストするこずはできたせん。 これはプラットフォヌムずしおの巚倧な切り札のJavaです。



質問に察する倚くの答え。 たずえば、各UIラむブラリのStackOverflow に関する質問の割合です 。







StackOverflowに関する玄100問ごずに、Swingに関する質問がありたす。 実際には、これはほずんどの問題がすでに解決されおいるこずを意味したす。 ほずんどの堎合、あなたが滞圚しない問題に䞀察䞀で察応したす。



やばい



前の郚分は、甘いプレスリリヌスのようなものです。 修正したした。 これはあなたが遭遇するかもしれないものです。



重倧なバグは修正されたせん。 File.existsはJDK7のリリヌス以降機胜しおおらず 、ただ修正されおいたせん。 バグが重倧な堎合でも、修正たで数幎埅぀こずができたす。



ネむティブコヌドを䜿甚する堎合、状況はさらに悪化する可胜性がありたす。 モヌダルりィンドりたずえば、OpenFileDialogを開くを䜿甚するず、䞀郚のコンピュヌタヌでフリヌズが発生する状況に遭遇したした。 Java Native Foundationは、ドキュメントの䟋に埓っお䜿甚されおいたす。 そしお、StackOverflowの恩恵は私を助けたせんでした:-)



file.existsのバグは、java.nioのクラスを䜿甚しお回避できたす。 これは、葉の倚いフォルダヌのパフォヌマンスの問題を解決するために蚭蚈された新しいAPIです。



あなたがする必芁があるこず

  1. –Dfile.encoding=UTF-8



    パラメヌタヌを䜿甚しおアプリケヌションを起動したす
  2. File.existsの代わりに、Files.exists Files.exists(Paths.get(fileName))



    を䜿甚したす
  3. File.listFilesの代わりに䜿甚したす

     try (DirectoryStream<Path> ds = Files.newDirectoryStream(folder)) { for (Path file : ds) { // do something } } catch (IOException e) { e.printStackTrace(); }
          
          





たたは、このバグを自分で修正し、䞀連のレビュヌでブックマヌクを抌しおください。



Swingはハヌドりェアアクセラレヌションのみです。 ぀たり、アプリケヌションはVMware、Parallels、たたはリモヌトデスクトップでは機胜したせん。 これに我慢する準備ができおいない堎合は、SWTに泚目しおください。



Mac甚の32ビットビルドはありたせん。 公匏ビルドは64ビットのみです。 残念ながら、この決定の理由は䜕なのかわかりたせん。 私はそれがいく぀かのバグの問題だず掚枬するこずができたす。



しばらくの間、Henri Gomezは32ビットおよびナニバヌサルビルドをサポヌトしおいたした。 既補のビルドは、code.google.comの圌のペヌゞからダりンロヌドできたす。 残念なこずに、時間の䞍足ず新しい仕事により、ヘンリヌはこのプロゞェクトを終わらせたした。 さよならを蚀っお、圌はビルドスクリプトをGitHubに投皿したした。

https://github.com/hgomez/obuildfactory



圌らの助けを借りお、MacおよびLinux甚のOpenJDKを構築できたす。 玠晎らしいですが、そうではありたせん。 これらのスクリプトでは、Mac甚の32ビットバヌゞョンはビルドされたせん。 JDK内には、Mac甚の厳密に64ビットバヌゞョンのアセンブリが保護されおいる膚倧な数の構成ファむルがありたす。 メむンファむルのキヌを倉曎し、壊れたアセンブリを取埗したす。 Henri Gomezが32ビットビルドをどのように収集したかは私にはわかりたせん。



ディストリビュヌションにJREを含めたす。 アプリケヌション配垃に関するオラクルの幹郚の意芋「タヌゲットプラットフォヌム甚のバンドルされたJREを備えたスタンドアロンの自己完結型むンストヌラは、より成功したアプリケヌション配垃モデルです」 ゜ヌス 。 この決定の最も可胜性の高い理由は、アプレットの膚倧な数の脆匱性です。JavaはFlashのSieveバナヌを採甚したした。



この制限は、Mac OS 10.7 LionでJavaを削陀したAppleによっお最も匷くサポヌトされおいたす。 たた、新しいシステムアップデヌトをむンストヌルするずきに匷制的にオフにしたす。



JRE 7の重量は玄100 MBです。 アヌカむブには玄50が取埗されおいたすが、残念ながら、曎新から曎新たでのJREのサむズは拡倧しおいるため、膚匵した配垃の問題を解決する必芁がありたす。



すべおのBufferedImageオブゞェクトがハヌドりェアアクセラレヌションを䜿甚するわけではありたせん。 BufferedImage.TYPE_INT_ *のみ。 したがっお、TYPE_4BYTE *で動䜜するJDK7からは、TYPE_3BYTEに䞀貫性がなくなりたす。



BufferedImageラスタのデヌタにアクセスするず、GPUを介した画像の描画が停止したす。 これが行われる理由は明らかです。ナヌザヌがデヌタを倉曎し、「完成した倉曎」方法がなく、それらをビデオメモリにい぀転送するかが明確ではありたせん。 少なくずもそれは論理的です。



Visual Watermarkでは、C ++ラむブラリを䜿甚しお画像をロヌドし、結果のピクセルをBufferedImageオブゞェクトに倉換する必芁がありたした。 䞀床に1ピクセルず぀倉曎するのは非垞に遅く、画像ラスタバッファに盎接曞き蟌む必芁がありたした。 ラスタヌでgetDataを呌び出すずすぐに、すべおの写真の加速が停止したした。 DataBufferIntのコヌドを調べお、リフレクションを䜿甚しおこの問題の解決策を芋぀け、小さなヘルパヌクラスを䜜成したした。



 import java.awt.*; import java.awt.image.*; import java.lang.reflect.Field; import sun.awt.image.SunWritableRaster; import sun.java2d.StateTrackableDelegate; // Standard library prevents image acceleration once getData() method is called // This class provides a workaround to modify data quickly and still get hw-accel graphics public class AcceleratedImage { // Returns data object not preventing hardware image acceleration public static int[] getDataBuffer(DataBufferInt dataBuffer) { try { Field field = DataBufferInt.class.getDeclaredField("data"); field.setAccessible(true); int[] data = (int[])field.get(dataBuffer); return data; } catch (Exception e) { return null; } } // Marks the buffer dirty. You should call this method after changing the data buffer public static void markDirty(DataBufferInt dataBuffer) { try { Field field = DataBuffer.class.getDeclaredField("theTrackable"); field.setAccessible(true); StateTrackableDelegate theTrackable = (StateTrackableDelegate)field.get(dataBuffer); theTrackable.markDirty(); } catch (Exception e) { } } // Checks whether current image is in acceleratable state public static boolean isAcceleratableImage(BufferedImage img) { try { Field field = DataBuffer.class.getDeclaredField("theTrackable"); field.setAccessible(true); StateTrackableDelegate trackable = (StateTrackableDelegate)field.get(img.getRaster().getDataBuffer()); if (trackable.getState() == sun.java2d.StateTrackable.State.UNTRACKABLE) return false; field = SunWritableRaster.class.getDeclaredField("theTrackable"); field.setAccessible(true); trackable = (StateTrackableDelegate)field.get(img.getRaster()); return trackable.getState() != sun.java2d.StateTrackable.State.UNTRACKABLE; } catch(Exception e) { return false; } } public static BufferedImage convertToAcceleratedImage(Graphics _g, BufferedImage img) { if(!(_g instanceof Graphics2D)) return img; // We cannot obtain required information from Graphics object Graphics2D g = (Graphics2D)_g; GraphicsConfiguration gc = g.getDeviceConfiguration(); if (img.getColorModel().equals(gc.getColorModel()) && isAcceleratableImage(img)) return img; BufferedImage tmp = gc.createCompatibleImage(img.getWidth(), img.getHeight(), img.getTransparency()); Graphics2D tmpGraphics = tmp.createGraphics(); tmpGraphics.drawImage(img, 0, 0, null); tmpGraphics.dispose(); img.flush(); return tmp; } }
      
      







次のように䜿甚する必芁がありたす。

 DataBufferInt dataBuffer = (DataBufferInt)bufferedImage.getRaster().getDataBuffer(); int[] data = AcceleratedImage.getDataBuffer(dataBuffer); //   AcceleratedImage.markDirty(dataBuffer);
      
      





既に衚瀺されおいる画像に察しおこのコヌドをテストしおいたせん。



組み蟌みのアニメヌションず半透明はありたせん。 javax.swing.Timerオブゞェクトは2぀のこずを行いたす。

  1. コンポヌネントのアニメヌションを䜜成できたす。
  2. クラスは単玔であるため、非垞に長い時間実行したす。


アニメヌションを簡単に䜜成できるTiming Frameworkラむブラリがありたす。 アニメヌションは次のように実行できたす。



 Animator viewAnimator = new Animator.Builder() .setDuration(duration, TimeUnit.MILLISECONDS) //    .setStartDirection(Direction.FORWARD) .setInterpolator(new AccelerationInterpolator(0.3, 0.7)) //     .setRepeatCount(1).addTarget(new TimingTargetAdapter() { @Override public void timingEvent(Animator source, double fraction) { //   repaint(); } @Override public void end(Animator source) { //  -    } }).build(); viewAnimator.start();
      
      





最も䞀般的に䜿甚されるアニメヌションは、䜍眮ず半透明です。 Swingが正垞な堎合、暙準コンポヌネントは半透明をサポヌトしたせん。 問題はグラフィック゚ンゞンの機胜ではなく、コンポヌネントにgetAlpha / setAlphaプロパティがないずいう事実にありたす。



GateKeeperのため、JavaアプリケヌションはMountain Lionで実行されたせん。 この問題を解決するには、Mac Developerプログラムに幎間99ドルでサむンアップする必芁がありたす。 代わりに、Appleはコヌドに眲名するための蚌明曞を発行し、問題はなくなりたす。

次のようなアプリケヌションでバンドルに眲名できたす。

codesign –s “Developer ID” –f “path-to-my-app.app”







合蚈で



私の意芋では、Swingの䞻な欠点は、重芁なバグが未解決のたたであるため、プラットフォヌムの将来に関する䞍確実性です。 ブラりザプラグむンの脆匱性のみが修正を埅っおいたす。 図曞通が攟棄されたずいう感芚が埗られたす。 他のすべおの問題はそれほど重芁ではありたせん。



そしお、これが本圓なら、私はずおも悲しくなりたす。 Swingでデスクトップアプリケヌションを䜜成するのは迅速か぀簡単で、膚倧な量の既補の無料のコヌドが存圚するためです。



圓分の間、私はオラクルの開発者がシステムの問題を解決する時間があるこずを望んでいたす。



曎新 Qtのコントロヌルのカスタマむズが可胜であるこずがわかったコメントから



silvanskyに感謝

曎新 Skyggedansナヌザヌは、Airがマルチスレッドサポヌトを远加したこずに気付きたした 。 これは、通信を構成できる远加のSWFファむルを犠牲にしお行われたす。



All Articles