i am working on GWT to make web application but now i need to make my web applications in Responsive design but GWT not support Responsive Design please help me.
GWT supports responsive design just like any other widget toolkit (OK, that's not exactly true, there are probably widget toolkits that do a better job): do your layout with HTMLPanel, FlowPanel, SimplePanel and responsive CSS, or go the active layout route with layout panels and doing calculations in your code (or in a custom layout panel).
You can make your layout responsive using CSS media queries.
For example, to make dialog boxes occupy 90% of the available horizontal space on devices that have screen size up to 640px, one can wrap the style inside #media block like this:
#media all and (max-width: 640px) {
.gwt-DialogBox {
width: 90%;
}
}
Unfortunately (as of today) GWT compiler does not support media CSS, so the code above will fail if you use it in conjunction with CssResource.
One of the approaches to this problem is to split your CSS resources into two files.
All default (desktop) CSS styles would go to the first file (e.g. main.css), and all your mobile overrides would go to the second file (e.g. mobile.css).
Note that style names that you want to override for mobile need to be tagged as #external in the main.css to avoid name obfuscation by gwt compiler.
main.css:
#external .mainNorthPanel;
.mainNorthPanel {
position: fixed;
top: 0px;
}
mobile.css:
#media all and (max-width: 640px) {
.mainNorthPanel {
position: absolute;
top: -3em;
}
}
In your application ClientBundle, use main.css in conjunction with your CssResource interface, and define the mobile file as an external resource:
public interface MyBundle extends ClientBundle {
public interface MainStyles extends CssResource {
String mainNorthPanel();
}
#Source("css/main.css")
MainStyles css();
#Source("css/mobile.css")
TextResource mobile();
}
And finally inject your external CSS resource somewhere in the module initialization:
String mobileCss = myBundle.mobile().getText();
StyleInjector.injectAtEnd(mobileCss)
For the full working example, take a look at this JavaWorld post that just came out recently:
http://www.javaworld.com/article/2842875/java-web-development/responsive-web-design-with-google-web-toolkit.html
It covers some basic concepts such css-based responsive views, dialogs, and menus.
And there is a little proof of concept on github:
https://github.com/cuppafame/gwt-responsive
In addition to what Thomas said you can look into gwt-bootstrap. They have a custom DataGrid widget that can be shown or hidden based on breakpoints (tablets, phones, etc).
If you actually want to hide and show columns based on available size you extend the DataGrid and do something along this lines:
ResponsiveDataGrid extends DataGrid<myDTO> {
private final Column<myDTO,String> column1;
private final Column<myDTO,String> column2;
private Boolean isCompact;
public ResponsiveDataGrid(int pageSize, Resources resources,ActionCell.Delegate<myDTO> actionDelegate) {
super(pageSize, resources,new EntityProxyKeyProvider<myDTO>());
initColumns();
}
private void initColumns() {
// init your columns
}
private void updateColumns() {
int columnCount = getColumnCount();
for (int i =columnCount-1;i>=0;i--) {
removeColumn(i);
}
removeUnusedColGroups();
if (isCompact) {
// show columns for compact size
}
else {
// show all columns
}
}
#Override
protected int getRealColumnCount() {
return getColumnCount();
}
// WORKAROUND for some sizing issues in DataGrid
private void removeUnusedColGroups() {
int columnCount = getColumnCount();
NodeList<Element> colGroups = getElement().getElementsByTagName("colgroup");
for (int i = 0; i < colGroups.getLength(); i++) {
Element colGroupEle = colGroups.getItem(i);
NodeList<Element> colList = colGroupEle.getElementsByTagName("col");
for (int j = colList.getLength()-1;j>=0; j--) {
colGroupEle.removeChild(colList.getItem(j));
}
}
}
#Override
public void onResize() {
super.onResize();
if (!isAttached()) {
return;
}
// or whatever breakpoint you want to support
boolean isNewCompact = (getOffsetWidth() < 800);
if (isCompact == null || isNewCompact != isCompact) {
isCompact = isNewCompact;
updateColumns();
}
}
}
/*The best way to do responsive web with is to use Timer class and Window class in GWT as Gwt does not responsive web at the moment. I have been searching on the web for about a week now and it was a waist of my time, even Google does not know how to do that. I came out with a very straight forward solution by using Window class and Timer class and it works like a magic.*/
public class View extends VerticalPanel{
private FlexTable flexTable=new FlexTable();
private Button[]buyAndSellButtons = new Button[2];
private TextBox[] textField=new TextBox[2];
private Label alert=new Label();
private LinkedList <String> stock=new LinkedList<>();
public View(){
createComponents();
}
public VerticalPanel createComponents() {
// Assume that the host HTML has elements defined whose
// IDs are "slot1", "slot2". In a real app, you probably would not want
// to hard-code IDs. Instead, you could, for example, search for all
// elements with a particular CSS class and replace them with widgets.
//
HorizontalPanel[] horizontalPanel = new HorizontalPanel[4];
for (int x = 0; x < horizontalPanel.length; x++) {
horizontalPanel[x] = new HorizontalPanel();
}
alert.setStyleName("alert");
add(alert);
flexTable.setText(0, 0, "BUY Orders");
flexTable.getCellFormatter().setStyleName(0, 0, "orderMatcherListHeader");
flexTable.setText(0, 1, "SELL Orders");
flexTable.getCellFormatter().setStyleName(0, 1, "orderMatcherListHeader");
flexTable.setStyleName("flexTable");
flexTable.setWidth("33em");
flexTable.setCellSpacing(5);
flexTable.setCellPadding(3);
add(flexTable);
Label[] labels = new Label[2];
labels[0] = new Label("Volume");
labels[1] = new Label("Price");
for (Label label : labels) {
label.setStyleName("label");
horizontalPanel[1].add(label);
horizontalPanel[1].setStyleName("labelPosition");
}
textField[0] = new TextBox();
textField[0].setTitle("Volume");
textField[1] = new TextBox();
textField[1].setTitle("Price");
for (TextBox textBox : textField) {
textBox.setStyleName("textField");
textBox.setFocus(true);
horizontalPanel[2].add(textBox);
}
buyAndSellButtons[0] = new Button("BUY");
buyAndSellButtons[1] = new Button("SELL");
for (Button button : buyAndSellButtons) {
horizontalPanel[3].add(button);
button.setStyleName("buttons");
horizontalPanel[3].setStyleName("buttonPosition");
}
VerticalPanel[] mainPanel = new VerticalPanel[1];
mainPanel[0] = new VerticalPanel();
for (HorizontalPanel aHorizontalPanel : horizontalPanel) {
mainPanel[0].add(aHorizontalPanel);
mainPanel[0].setStyleName("mainPanel_1");
setStyleName("mainPanel");
add(mainPanel[0]);
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent event) {
alert.setText("" + Window.getClientWidth());
}
});
}
Timer timer=new Timer() {
int x;
#Override
public void run() {
alert.setText(Window.getClientWidth()+"Attach" + x++);
String[] gadget=new String[10];
gadget[0]=("354"); //android portrait
gadget[1]=("625");
gadget[2]=("314");
gadget[3]=("474");
gadget[4]=("369");
gadget[5]=("562");
gadget[6]=("617");// android landscape
gadget[7]=("48");
gadget[8]=("730");
alert.setText("" + Window.getClientWidth()+x++);
if(Window.getClientWidth()<=425) {
flexTable.getCellFormatter().setStyleName(0, 0, "orderMatcherListHeader_1");
flexTable.getCellFormatter().setStyleName(0, 1, "orderMatcherListHeader_1");
mainPanel[0].setStyleName("phonePortrait_1");
setStyleName("phonePortrait");
flexTable.setStyleName("flexTable_1");
if(Window.getClientWidth()==414){
flexTable.setWidth("26.2em");
}{
flexTable.setWidth("24.2em");
}
flexTable.setCellSpacing(5);
flexTable.setCellPadding(3);
}
else if((Window.getClientWidth()>425)&&(Window.getClientWidth()<=812)) {
alert.setText("" + Window.getClientWidth());
flexTable.getCellFormatter().setStyleName(0, 0, "orderMatcherListHeader_1");
flexTable.getCellFormatter().setStyleName(0, 1, "orderMatcherListHeader_1");
mainPanel[0].setStyleName("phoneLandScape_1");
setStyleName("phoneLandScape");
flexTable.setStyleName("flexTable_1");
flexTable.setWidth("24.2em");
flexTable.setCellSpacing(5);
flexTable.setCellPadding(3);
}else {
return;
}
}
};
timer.scheduleRepeating(500);
return this;
}
Related
I am using Marker clusters in my application. I want to increase the grid size. I have customize the DefaultClusterRenderer class, but I didn't find any thing in it to increase the size.Please help me out how to increase it.
following is the code of customized clusterRenderer
public class MyClusterRenderer extends DefaultClusterRenderer<MyItem> {
public MyClusterRenderer(Context context, GoogleMap map, ClusterManager clusterManager) {
super(context, map, clusterManager);
}
#Override
protected boolean shouldRenderAsCluster(Cluster<MyItem> cluster) {
//start clustering if at least 2 items overlap
return cluster.getSize() > 4;
}
#Override
protected void onBeforeClusterItemRendered(MyItem item,MarkerOptions markerOptions){
if(item.isRegister()==true)
{
BitmapDescriptor markerDescriptor = BitmapDescriptorFactory.defaultMarker(340);
markerOptions.icon(markerDescriptor);
//markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.x));
}
else if(item.isRegister()==false)
{
BitmapDescriptor markerDescriptor = BitmapDescriptorFactory.defaultMarker(60);
markerOptions.icon(markerDescriptor).title("false");
}
}
}
A simple solution is use the NonHierarchicalDistanceBasedAlgorithm. Create a new calss and extends it with NonHierarchicalDistanceBasedAlgorithm, then override the method getClusters(double zoom). In this method you will be able to set the grid size, by changing the value of zoomSpecificSpan, In my i change the first value to 200.0D, and it works for me.
public Set<? extends Cluster<T>> getClusters(double zoom) {
int discreteZoom = (int)zoom;
double zoomSpecificSpan = 200.0D / Math.pow(2.0D, (double)discreteZoom) / 256.0D;
HashSet visitedCandidates = new HashSet();
HashSet results = new HashSet();
HashMap distanceToCluster = new HashMap();
HashMap itemToCluster = new HashMap();
PointQuadTree var10 = this.mQuadTree;
I want a timer that switches screens after a certain amount of time. Here is the code for my splash screen:
private boolean timerIsOn = false;
And here is the render() method code:
if(!timerIsOn) {
timerIsOn = true;
Timer.*schedule*(new Task() {
#Override
public void run() {
*changeScreen*();
}
}, 15);
} else if(Gdx.input.isTouched()) {
// Remove the task so we don't call changeScreen twice:
Timer.instance().clear();
*changeScreen*();
}
}
I'm getting red swiggly lines under the parts of the code that have * and * surrounding them but the suggested action to fix it doesn't help.
Also, if you know of an easier way to make this work or possibly a tutorial that would be great as well.
The portable class library defines the start view model. This scenario generally sounds great but I was considering this. You have written a iOS universal application or Android that needs to change its start screen / view model. If application is a phone, the default view model is login but if it is tablet, you want a different view model as the start. Is there an override or a way to take control of this?
See the Wiki section - https://github.com/MvvmCross/MvvmCross/wiki/Customising-using-App-and-Setup#custom-imvxappstart - this has an example of programmatic switching:
If more advanced startup logic is needed, then a custom app start can be used - e.g.
public class CustomAppStart
: MvxNavigatingObject
, IMvxAppStart
{
public void Start(object hint = null)
{
var auth = Mvx.Resolve<IAuth>();
if (auth.Check())
{
ShowViewModel<HomeViewModel>();
}
else
{
ShowViewModel<LoginViewModel>();
}
}
}
This can then be registered in App using:
RegisterAppStart(new CustomAppStart());
In your App class you could register an AppStart that is a splash screen:
RegisterAppStart<SplashScreenViewModel>()
In that splash screen you could receive a service that verifies if it's a tablet or a phone. You would need to create a plugin to make this verification. (There are other stackoverflow questions showing how to verify this / How to detect device is Android phone or Android tablet? )
public SplashScreenViewModel(ITabletVerificationService tabletVerificationService)
Then you would simply change screen according to this service
if(tabletVerificationService.IsTablet())
{
ShowViewModel<TabletViewModel>
}
else
{
ShowViewModel<LoginViewModel>
}
Hope it helps =)
Here's my implementation of this scenario, if it could help:
PCL:
public enum PlateformType
{
Android,
iPhone,
WindowsPhone,
WindowsStore
}
public interface IPlateformInfos
{
PlateformType GetPlateformType();
}
public class CustomAppStart
: MvxNavigatingObject
, IMvxAppStart
{
public void Start(object hint = null)
{
var plateformInfos = Mvx.Resolve<IPlateformInfos>();
var plateformType = plateformInfos.GetPlateformType();
switch (plateformType)
{
default:
ShowViewModel<MenuViewModel>();
break;
case PlateformType.WindowsPhone:
case PlateformType.WindowsStore:
ShowViewModel<FirstViewModel>();
break;
}
}
}
PCL App.cs:
RegisterAppStart(new CustomAppStart());
UI (ex: WindowsPhone):
public class PlateformInfos : IPlateformInfos
{
public PlateformType GetPlateformType()
{
return PlateformType.WindowsPhone;
}
}
UI Setup.cs:
protected override void InitializeFirstChance()
{
Mvx.RegisterSingleton<IPlateformInfos>(new PlateformInfos());
base.InitializeFirstChance();
}
Pretty simple way.
I just started programming OOP and I'm running into a scope problem.
In the following project, I have a masterClass called App. The App-class has Screens:Screen-class and a Navigation-class as it's children. From the navigation class I want to control which screens will be displayed. I don't know how to do this...
Please check the code to fully understand my intentions
Your help is really appreciated, I'd love to really learn programming and not just a dirty solution :) but all suggestions are welcome!
// Main Class //
public class App extends Sprite
{
private var screens:Array;
private var screen1:Screen;
private var screen2:Screen;
private var screen3:Screen;
private var screen4:Screen;
public var currentScreen:String;
//
private var navigation:Navigation;
public function App()
{
init();
}
private function init():void {
buildScreens();
buildNavigation();
}
private function buildScreens():void {
screen1 = new Screen();
screen1.name = 'startScreen';
currentScreen = screen1.name;
addChild(screen1);
screen2 = new Screen();
screen2.name = 'irrelevantA';
screen3 = new Screen();
screen3.name = 'irrelevantB';
screen4 = new Screen();
screen4.name = 'irrelevantC';
screens = new Array(screen1, screen2, screen3, screen4);
}
private function buildNavigation():void {
navigation = new Navigation(screens);
}
}
// Screen Class //
public class Screen extends Sprite
{
public function Screen()
{
// creates a new screen
}
}
// Navigation Class //
public class Navigation extends Sprite
{
private var buttons:Array;
public function Navigation(screens:Array)
{
addButtons(screens);
}
private function addButtons(screens:Array):void {
buttons = new Array();
for each(var screen:Screen in screens) {
var button:Button = new Button();
button.link = screen.name;
button.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
buttons.push(button);
}
}
private function mouseDown(e:MouseEvent):void {
// THIS IS WHAT MY QUESTION IS ABOUT: How should I talk to the parent class in an OOP correct way?
// and how can I add and remove a screen in the App class from here?
// Here some of my tries
// I don't think using parent to get there is a good way because next time it might be; parent.parent.parent
trace(e.target.parent.parent.currentScreen);
this.parent.currentScreen;
stage.App.currentScreen;
App.currentScreen;
//---------------------------------
}
}
// Button Class //
public class Button extends Sprite
{
public var link:String;
public function Button()
{
// creates a new button
}
}
If you directly access parent classes from child objects, you create strong coupling - which is exactly what you don't want in a well-built system. It is best not to access the application object directly, but to use event listeners and custom events to promote changes from e.g. the navigation.
Here's an example. First, create a custom event:
public class MyCustomEvent extends Event {
public static const MENU_ITEM_SELECTED : String = "MENU_ITEM_SELECTED";
public var selectedItem:String;
}
Then, let the navigation dispatch it, when a button is clicked:
public class Navigation extends Sprite () {
// ...
private function onButtonClicked(ev:Event) : void {
ev.stopPropagation();
var custEvent:MyCustomEvent = new MyCustomEvent(MyCustomEvent.MENU_ITEM_SELECTED);
custEvent.selectedItem = ev.target.name;
this.dispatchEvent (custEvent);
}
// ...
}
Finally, let the application handle the custom event and bring up a different screen:
public class App {
// ...
public function createNavigation () : void {
navigation = new Navigation ();
navigation.addEventListener (MyCustomEvent.MENU_ITEM_SELECTED, onMenuItemSelected);
// ... more stuff happening
}
// ...
private function onMenuItemSelected (ev:MyCustomEvent) : void {
switchToScreen (ev.selectedItem);
}
private function switchToScreen (name:String) : void {
// choose screen by name, etc.
}
}
For all of this, neither the screen, nor the navigation have to know anything about any other objects involved, so you can easily replace each one without breaking the rest of the system.
You basically want to communicate downward (parent to child) by passing in references as arguments (as you're doing with the screens array) and upwards (child to parent) by calling public functions.
So, in your case something like this:
App class:
private function buildNavigation():void {
navigation = new Navigation(this, screens);
}
//etc
public function changeScreen(newScreen:int):void{
//Your logic for adding/removing screens goes here
}
Navigation class:
private var app:App
public function Navigation(app:App, screens:Array)
{
this.app = app
addButtons(screens);
}
private function addButtons(screens:Array):void {
buttons = new Array();
for each(var screen:Screen in screens) {
var button:Button = new Button();
button.link = screen.name;
button.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
buttons.push(button);
}
}
private function mouseDown(e:MouseEvent):void {
app.changeScreens(2);
}
}
Obviously, change the implementation to suit your needs (for example, now that you have a reference to the App class, consider if you need to pass in a separate reference to the screens array or not) - this is just an example of how you can communicate.
Is there a way of hiding Common properties of Web Parts? The Layout or appearance section for example.
I have created a new visual web part and I wan't to make it very easy to edit for the administrators and they don't need the standard layout / appearance settings when they go to 'edit web part'
Any ideas how to hide the base properties from the edit panel? Been searching all over but can't see anything in the documentation.
Here's one way to achieve this. In your EditorPart, mark the container of the other EditorParts as not Visible:
class EditorPartTest : EditorPart
{
protected override void CreateChildControls()
{
Parent.Controls[1].Visible = false;
Parent.Controls[2].Visible = false;
base.CreateChildControls();
}
public override bool ApplyChanges()
{
return true;
}
public override void SyncChanges()
{
}
}
And use it from your web part like this:
public class VisualWebPart1 : WebPart
{
public override EditorPartCollection CreateEditorParts()
{
ArrayList partsArray = new ArrayList();
EditorPartTest editor = new EditorPartTest();
editor.ID = this.ID + "_editorPart";
partsArray.Add(editor);
return new EditorPartCollection(partsArray);
}
}
Then you should get a result like this:
http://joelblogs.co.uk/?attachment_id=10785
Hope this helps!
joel
joelblogs.co.uk
SharePoint Architect Blog