为什么很难使Java程序“本机显示”?


98

大多数Java应用程序看起来与C / C ++应用程序不同。Swing可能被设计为具有独特的外观,但是根据我的阅读,例如SWT试图“看起来很自然”,但没有成功。

我的问题是:

对于Java语言的开发人员来说,为什么要设计出完全复制本机GUI 外观的GUI系统很困难?本机GUI有什么不同?设计不仅仅是看起来像“本机”按钮的按钮吗?还是比这更深入?


31
因为在可移植性的概念中,swing编写了自己的gui组件来尝试模仿本机组件,而不是创建对实际本机组件的绑定,所以它具有可移植性
棘手的怪癖2014年

5
我不是这个主题的专家,但是我想这只是GUI工具包供应商愿意投入多少精力来正确处理所有棘手细节的问题。见,例如,C ++ framwork“Qt的”,这太问题:stackoverflow.com/questions/7298441/...
布朗博士

4
有很多细节要注意。例如,在文件打开对话框中自动完成的工作方式是本地Java应用程序崩溃的一个方面。
CodesInChaos 2014年

4
Swing具有“本机外观”外观,您可以插入该外观而不是默认外观。另外,Java最初尝试将可用的本机资源与AWT一起使用,但由于平台之间的固有差异,它不能很好地运行,即AFAIK。这就是为什么他们创建了Swing,以便Java应用程序在任何地方都可以完全相同的原因。
marczellm 2014年

5
不要忽视JavaFX。它是SWING的替代品,默认情况下从Java 8开始在JDK / JRE中使用。它比SWING和AWT更为现代,并且在几乎所有平台上看起来都更加原生(它在每个平台上都与原生UI工具包挂钩)平台)。就像其他人提到的那样,要想从像Java这样的“千篇一律”的语言中获得完全本机外观的应用程序,您将需要做一些工作。Java的UI曾经/曾经/仍然是现成的,“最适合所有平台”。
SnakeDoc

Answers:


56

设计不仅仅是看起来像“本机”按钮的按钮吗?

好吧-对于按钮。但这可能比您想象的要难。如今,用于表示GUI组件的图形已不像被拉伸的随机位图那样简单(因为它们根本无法很好地缩放)-它们通常是基于矢量的图形,并且在其中编写了许多角落情况(因此,当按钮到达屏幕边缘时,它看起来可能会略有不同。)当然,单击按钮时,您将需要不同的图形。出于版权原因,开发人员通常不能直接使用这些现有图形,因此必须重新创建它们-尽管它们在很大程度上做得很好,但由于那里存在大量图形组件,不可避免地会遗漏一些东西。

我说的是基于Swing的所有上述内容,它当然是轻量级的非本地GUI工具包。您特别提到SWT看起来不是本地的,这有点奇怪,因为SWT 是本地的。这是一个在下面使用JNI来调用本机组件的工具箱-因此,如果那里看起来不正确,那不是因为外观。


1
谢谢。“轻量级”到底是什么意思?“本地”到底是什么意思?我认为这意味着使用计算机操作系统资源或与其直接交互的事物。这是真的?
user3150201 2014年

1
@ user3150201当然,因此底层操作系统将具有一定数量的按钮和小部件,这些按钮和小部件可以本地放置,但是显然,这些按钮在操作系统之间和平台之间会有所不同-这些是重量级的本地组件。轻量级组件不是操作系统规定的组件,它们是由Java(在这种情况下)绘制的,其外观和行为类似于GUI组件-因此,如果将其放入其中,它们可以根据您的需要进行外观(但您必须模拟)平台的外观和感觉,如果您想要的话,您就不会免费获得它。)
berry120 2014年

14
按钮的位置,确切的大小以及首选的GUI样式因平台而异,并且使Java模仿它们的工作量很大。Swing可以为您提供本机按钮,但是如果它高10像素,则用户仍会认为有些问题。Apple具有人机界面指南,而Microsoft具有用户界面指南可帮助您获得正确的本机外观。您将需要在平台之间稍作更改UI。
Michael Shopsin

4
JavaFX看起来比SWING和AWT更“原生”。它具有本机透明窗口等。开箱即用的外观更加现代。
SnakeDoc

2
@SnakeDoc当然,它看起来更现代,但是我不会说它看起来是“本机”的-它当然不使用平台的底层GUI组件,它们全都用CSS蒙皮。
berry120 2014年

71

在某些系统上,实际上有六种工具箱可以被视为“本机”。其中一些具有相当独特的概念或功能,因此在跨平台工具箱中复制它们很乏味。应用程序的外观不仅取决于“外观”,还取决于布局及其行为方式。一些注意事项:

  • 在对话框中,“确定”按钮属于哪一侧-左侧还是右侧?公平地说,让我们为每个系统构建一个单独的对话框。
  • 我们如何在屏幕上标记默认按钮?颜色,粗体,按钮是否放大?公平地说,我们将其放在样式表中。
  • 在Windows上,“ Ribbon”的概念很原始。如何将其转换为功能区不常见的Mac?公平地说,让我们忘记像素精确的布局,并为每个系统提供不同的工具栏实现。
  • 菜单栏是窗口的一部分(Windows,还是KDE),还是位于屏幕顶部(Mac,Unity)?公平地说,让我们为每个系统编写不同的实现,因为我们已经舍弃了像素精确的布局
  • 字体如何呈现?尽可能脆,还是光滑且抗锯齿?以及应该使用什么字体?请注意,不同的字体具有不同的度量标准,因此根据字体的不同,呈现为相同宽度的同一段落可能具有不同的行数。
  • 窗口的背景是单色,图像还是渐变色?我们也将其放入样式表中。
  • 滚动条外观如何?按钮在哪里–如果有的话?它们有多宽?或者仅在指针移至某个区域时才显示出来?
  • 我们如何结合其他配色方案?
  • 预期什么是可拖动的?上下文菜单在哪里?

当这些问题涉及应用程序的行为或总体布局时,无法通过简单的样式表解决。唯一真正的解决方案是为每个系统重新编写应用程序(从而忽略Java的跨平台优势)。唯一可行的解​​决方案是忘记像素精确的布局,并写入一个通用接口,该接口可对特定于系统的工具包进行抽象。Swing采取的解决方案是模拟各种系统,但失败极多。

然后是跨平台的一致性,即您的应用程序在所有系统上看起来完全一样的想法(通常是游戏选择的,这会增加沉浸感)。在桌面应用程序上,这很烦人并且破坏了用户的期望。


1
+1。我只想补充一件事:从允许用户打开上下文菜单之类的“简单”细节开始,系统允许用户进行配置的事情是什么?(而且,我非常希望Windows程序不要具有功能区和Mac应用程序,谢谢。是的,需要针对每个OS设计好的GUI。)
Christopher Creutzig 2014年

@ChristopherCreutzig这就是我的经验所来自的地方:在我的主桌面上,我在Linux上使用KDE(两者都可以很容易地配置),并使用QtCurve调整应用程序的外观。这些特殊样式在旗舰级KDE应用程序中可以正常工作。编写良好的GTK应用程序可以利用兼容性层,但是缺少背景渐变,菜单栏停留在窗口内等。但是随着程序从系统样式中获取一些小部件(例如滚动条),它很快就开始恶化。 ,但忽略其他内容(例如字体渲染或菜单周围的阴影)
2014年

+1是因为此答案中有一些优点,但也有一些缺点。任何“此窗口管理器如何绘制X”问题都可以通过使用本机API处理。例如,OS X上的X11可以绘制本机OS X的窗口,按钮,滚动条,对话框等。因此,许多这些问题都消失了。在真正的答案是什么@TheSpooniest下面说:UX是这么多的不仅仅是绘制控件。间隔,定时,动画,鼠标加速,触摸输入...存在着许多细微的细节,而这些细节要用跨平台工具包进行复制,成本很高。
Mark E. Haase 2014年

13

是的,它的确更深入。

仅构建此按钮时,构建看起来像Windows或OS X按钮的按钮很容易。但是按钮必须像原始按钮一样“表现”,这可能并不容易:一个版本中可能有更多空间,而另一个版本中没有,可能颜色更适合Windows版本中的设计,等等。

当您拥有一个完整的GUI时,这会变得更加糟糕:OS X程序与Windows程序呈现的内容不同。这几乎不可能在一个GUI中捕获-您将需要两个GUI,但是很少有应用程序引起如此大的麻烦。取而代之的是,他们的目标是“在大多数系统上看起来都不错”-看起来仍然有些陌生,但实用且易于开发。


9

创建一个看起来像OSX按钮,Windows按钮或任何其他工具包的按钮并不难。但是,大多数环境的UI准则并不像“这就是按钮的外观”的基础那么简单。从UI元素之间的间距到某些众所周知的动作应在列表中显示的顺序,到菜单系统中“首选项/选项”对话框的确切位置,都有许多细微的差别。对于非常简单的用户界面,可以自动执行最常见的情况,但是即使不是大多数UI任务,许多情况也需要更好的操作。

SWT试图在某种程度上实现自动化,并且再次使其适用于简单的UI任务。但是,还没有一种万能的解决方案,因此,当UI变得更加复杂时,它使用的基本方法就开始瓦解。通常可以使它与艰苦的手动UI工作保持一致,但这并不是大多数程序员能够或不愿意在所有平台上做到的事情。

Swing的方法只是尽可能地避开本机工具箱。它不是本机的,也没有尝试成为的:相反,它尝试创建无论在何处运行都看上去(几乎)相同的东西。它并没有试图(徒劳地)取悦所有人,而是试图取悦自己,尽管它取得了成功,但人们可以质疑结果对更广泛的用户群体有多有效。


7

在期望您的应用程序在每个系统上看起来都尽可能自然,以及期望您的应用程序在每个系统上以相同的方式工作之间需要权衡。没有“正确”的选择。

此外,即使您选择“自然外观”,您也可能希望保护图形工具包的用户免受基础本机组件和API的“改进”,这可能会意外破坏其应用程序。

这就是为什么某些GUI工具包开发人员倾向于提供自己的组件来模仿本机组件,但提供自己的实现。另一方面,开发功能完善的GUI工具包是一项巨大的工作,并且出于经济考虑,可能会导致一些不足。

请注意,此问题不是Java特有的,但是每家生产平台独立工具包的公司都面临该问题。


与其默默地投票,不如通过解释自己的回答有问题,可以为社区提供更好的服务。除非只是个人问题...
Nicola Musatti

4

这都是由于历史。

Sun希望所有Java软件在所有机器上都可以相同地工作。

为了使软件“出现在本地”,它必须与给定OS上的其他软件相同。

Sun竭尽全力使编写与OS集成的Java软件变得困难,因为与OS的任何集成都会使软件在每个OS上的工作方式有所不同。

如今,除了基于Web服务器的软件之外,几乎没有Java程序员关心其他任何事情。

Sun通过招募所有使用基于Microsoft Java的系统的程序员来杀死台式机上的Java,因此使任何早期选择Java的程序员看起来都很糟糕。

编写桌面软件的任何人都在乎“出现本机”,很久以前就学会了不使用Java,并且在每次使用任何Oracle软件时都会增强其观点。

因此,如今,Java程序员不再需要在桌面软件上“本机显示”。


5
“ Sun竭尽全力使编写与操作系统集成的Java软件变得困难,”这是错误的。他们只是简单地付出了很大的努力。“ Sun强迫所有使用基于Microsoft Java的Java的系统的程序员杀死了台式机上的Java”,这是错误的,Microsoft与Sun的相互敌视导致Microsoft创建了一个与Sun要求不兼容的AWT库版本,从而声名狼藉。 Sun / MS诉讼。
jwenting 2014年

1
@ jwenting,Sun更关心为微软制造问题,然后更关心选择使用微软基于Java的系统的程序员。因此,放弃了Jave并继续使用MFC,直到C#出来。
2014年

3
也许在Sun有一些人,但是这种感觉是相互的。如果您是专门为单个平台开发的,则始终首选该平台的本机工具,这与公司政策无关。如果您基于“我讨厌Sun”或“我讨厌微软”来选择工具,这些工具在您的专业态度上反映得很差。我主要使用Java,但除此之外,我还使用了Delphi,C#,Ruby,C ++,C,Progress,无论是最适合手头的工作。而且多数情况下,最终将成为混合解决方案。
jwenting

3

您认为native实际上是本机应用程序在做自己的事情,而像SWT这样的工具箱则遵循该OS的UI的已发布标准。问题是没有人会遵循这些标准来构建应用程序,因此在启动Java应用程序时会如此。它似乎不是本地的。例如,几乎所有Microsoft项目(Office,Outlook等)都无法使用Windows标准控件直观地进行复制。

随着Microsoft和Apple都向其OS平台添加动态UI功能,情况将变得更加糟糕。允许开发人员以与网站设计创建网站样式相同的方式对应用程序进行外观/样式设置。

Android平台上的Java遵循此路径。使用可换皮肤的样式制作以XML定义的Android的UI元素。

Java从未作为桌面平台非常流行。结果,行业中的这些变化没有传播到桌面运行时。只是没有足够的开发人员愿意花时间来解决此问题。


1
+1,回到Windows 95时代,Windows控件有了“标准”外观。现在,不是很多。
GrandmasterB 2014年

是的,自从我为台式机编程以来已经有好几年了,但是令我惊讶的是.NET并未附带功能区样式控件,尽管它已成为MS内置的生产力软件的组成部分。
钻机

@Rig自NET 4.0以来,.NET中具有良好的本机Ribbon控制。这是一篇好文章:c-sharpcorner.com/UploadFile/0b73e1/ribbon-control-in-wpf-4-5
Christian Sauer

1
@Rig您将需要.NET 4.5,而不是.NET4。VisualStudio 2010最多只能定位4个。您需要VS2012或更高版本才能定位4.5。我可以看到它瞄准4.5 VS2013的时候,而不是当我的目标版本更改为4
鲍勃

1
@Rig可以在Net 4.0中使用功能区-您可以从Microsoft下载它,然后它会显示出来:10rem.net/blog/2010/10/22/wpf-ribbon-october-release(不确定是否是最新版本)。最好从Nuget下载。对于必须在Windows XP上运行的程序,我必须这样做-可以正常运行,并且与Net 4.5变体兼容,因此在XP最终退出时,您可以淘汰4.0。
Christian Sauer 2014年

-1

您还希望哪个操作系统看起来“本机”?

您只是不可能 100%地都是所有人的本地人。

SWT等是尽力而为的方法,当您需要做出一些妥协时,它们看起来就像它们所有人一样。

实际上,这种折衷开始变得越来越难以实现。不是因为操作系统,而是因为输入设备。对于触摸屏,您实际上必须进行不同的设计,因为没有鼠标右键。因此,否则,您需要适应相同的功能。

除非为每个输入设备指定每个详细方面,否则,永远不会有一个魔术按钮将功能从鼠标右键“直观地”转移到客户(此时,您是所考虑的每个平台的本地用户,但是仍然无法使用) -与您尚未考虑的任何内容相比)。


-2

真的很好的问题。在过去的几年中,我一直想知道这个问题,我认为这背后有一些合法的理由,但实际上没有。

我认为答案很简单,很多答案并未真正解决问题。

如果您的语言允许在屏幕上绘制Piexel,则有可能100%基于它创建一个GUI框架,该框架将模仿Windows窗体控件的外观。

由于Java是跨平台的,因此完全有可能确保基于实际运行的系统类型(Mac / Windows),UI将选择在两个平台上看起来都不同,以匹配运行时平台样式。

如您在XAML中所见,例如,UI可以很容易地以结构化的形式和语言呈现。如果花时间去做,那么选择“本地”行为也是可能的。

因此,有可能创建GUI框架,该框架将允许Java开发人员获得在Mac和Windows上看起来本机的应用程序。

因此,我们来谈谈Swing,这仅仅是一个可以为Java创建的GUI框架的无限无限的GUI框架。它的行为方式是如何编程的,而没有遵循上述过程,因此您会在两个系统上都看起来很奇怪。那就是Swing开发人员的选择,没有人强迫他们这样做并表现出这种行为。


2
这并不能解决问题,问问者已经涵盖了这一点:“摆动可能是故意设计的,以具有独特的外观”
gnat 2014年

我不同意,但感谢您评论您的减号(?)
Valentin Kuzub 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.